430 likes | 444 Views
Explore the power and efficiency of the Standard Template Library (STL) in C++ programming, offering a comprehensive overview, examples, and benefits of leveraging STL for streamlined development.
E N D
STL Overview Intended audience: • C/C++ programmers not already expert in STL. • Visual Basic and Java programmers - see what you’re missing! • Managers - see why should your staff be competent in STL. • Others either you’re here for the cookies, or you’re in the wrong room? Please take your seats, and fasten your seat belts. Our flight will last approximately 1 hour, we’ll be flying over STL at mach 2, at an altitude of 70,000 feet. HANG ON! STL Overview - by Mark Bartosik October 2000
Audience • Non C++ programmers 40% • C++ programmers but without STL 35% • Experienced C++/STL programmers 10% • Managers <10% • Others <10% I hope that there is something here for all.Feel free to ask questions. STL Overview - by Mark Bartosik October 2000
The Goal • Q> How can software engineers write less code, write it quicker, and with less bugs? • Use the right technologies (breadth of knowledge) • Use technologies better (depth of knowledge) • Reuse code (a mythical goal) C++ is a mature technology, it may lack sex appeal now, it is not buzz-word compliant or bandwagon ready! However, with STL C++ can be a highly expressive, efficient, and a robust environment. Translation -boring? STL Overview - by Mark Bartosik October 2000
What is STL ? • Standard Template Library • So it’s yet another library? NO Not only is STL part of the C++ runtime library, and thus an ISO standard, and available across platforms, but it is the most powerful and imaginative library I have come across. It is so powerful that the ISO C++ standard was rewritten, and delayed by over 2 years so that it incorporated. The rest of the C++ runtime library borrows concepts from STL. STL Overview - by Mark Bartosik October 2000
Where is STL ? STL is part of the C++ runtime library • C runtime library (CRT) • time(), strcpy(), strstr() • streams • std::istream<>, ostream (vendors support new and old versions) • strings • std::string, std::wstring, std::basic_string<> • STL • std::vector<>, std::map<>, std::find, std::transform • misc • std::exception, std::locale STL Overview - by Mark Bartosik October 2000
Where’s the proof ? • STL will not save the world or cure the cold. It will not help much with GUI or database programming either. • But it can revolutionize infrastructure code! • An exercise for the audience: Take 1 minute to think about how you would write a program in any language to take a text file, and produce a dictionary file. Each word from the text file must appear exactly once in alphabetical order in the output file, punctuation must be stripped, but case can be ignored. STL Overview - by Mark Bartosik October 2000
Done it? • How complex is the task? • How much code will you have to write? • How much code will you have to debug? • How many bugs will you find? • How many bugs won’t you find!! STL Overview - by Mark Bartosik October 2000
Pseudo answer • Read each word into memory ignoring punctuation. • Sort the words. • Write to file But how much code does each of these steps take? The more code the more bugs! STL Overview - by Mark Bartosik October 2000
STL - the concept less bind1st find bind2nd copy int, long, string, your_class_t, etc. remove count_if transform vector<> list<> deque<> algorithms & types map<> multimap<> function objects set<> multiset<> valarray<> many more +streams<> algorithms & +hashtables<> function objects Glued together containers with "iterators" utility_of_STL== types x containers x (algorithms + functors); sizeof(STL) == containers + algorithms + functors; STL Overview - by Mark Bartosik October 2000
Solutions in STL • Both STL based solutions are much less complex than the alternative. • Why two STL solutions? To REALLY prove my point! • The example code is probably one of the most important parts of this talk, because it shows how using STL can make code more simple. STL Overview - by Mark Bartosik October 2000
Reuse The standard C++ library including STL is full of very useful functions, algorithms, function objects, containers, types, and iterators. All this code already works and has been debugged*. The more of it you can use, the less new code you have to write, and the less bugs you’ll have. *The library that ships with VC5 & 6 is based on a 1996 standard and has several bugs. The code examples here were compiled with a 2000 version STL Overview - by Mark Bartosik October 2000
Type safety the problem Example problem:Q> Create a reusable container that can store objects of any type. • Most traditional solutions, in most languages C, early C++, Visual Basic, Small Talk, Java, turn to polymorphism or type-less pointers. But beware when you see that the items in the container look like this: varient, object, void *, CObject *, base_class *, IUnknown * The language is probably being asked to determine how to treat an object at runtime. Everything runs smoothly when the object is of the expected type, but when it is not, you are risking a runtime error. The problem is that there is no guarantee that the container really contains only apples, some code in the depths may occasionally add an orange or two. STL Overview - by Mark Bartosik October 2000
Templates - the solution • Microsoft’s alternative “solutions” include using the pre-processor, or a wizard to generate custom code for each different type. • The preprocessor usually just hides or obfuscates the problems. • Wizards just generate more code (with more bugs) for you to maintain. • The C++/STL solution is templates. With templates you write the container using one piece of generic code. The compiler generates custom code for each type on demand. Errors occur at compile time rather than runtime. template<typename T> void print_all(const T & col){ std:copy(col.begin(), col.end(), std::ostream_iterator<T::value_type>(std::cout, “,”));} STL Overview - by Mark Bartosik October 2000
STL containers Unsorted containers std::vector<T>dynamic arrayprefer this to char * p = new char[n]; std::list<T> doubly linked list std::deque<T> like a vector but you can insert at the front and back Sorted containers std::set<T> a sorted set of unique values std::multiset<T> a sorted set of values, there may be duplicates Sorted associative containers std::map<key_t, value_t> an associative array, like a database table with a unique key field and one other field std::multimap<key_t, value_t> like map, but the record keys do not need to be unique STL Overview - by Mark Bartosik October 2000
Other containers The C++ runtime library std::string<T> a string of characters (wide or narrow) std::valarray<T> used for efficient vector processing mathematics Streams?std::istream, std::ostream, std::iostream AdaptersThere are also STL “adapters” that are wrappers on the STL containersstd::stack, std::queue (FIFO), std::priority_queue. Non standardHash tables STL Overview - by Mark Bartosik October 2000
The vector std::vector<T> my_vector; my_vector.begin() my_vector.end() T T T T my_vector.push_back(t) STL Overview - by Mark Bartosik October 2000
The vector Vectors have the following functions, and sub-types: allocator_type · assign · at · back · begin · capacity · clear · const_iterator · const_pointer · const_reference · const_reverse_iterator · difference_type · empty · end · erase · front · get_allocator · insert · iterator · max_size · operator[] · pointer · pop_back · push_back · rbegin · reference · rend · reserve · resize · reverse_iterator · size · size_type · swap · value_type · vector and a variety of operators like ==, !=, <, >, <=, >=, [] There is a lot of useful functionality here. STL Overview - by Mark Bartosik October 2000
The list std::list<T> my_list; my_list.begin() T T T my_list.end() STL Overview - by Mark Bartosik October 2000
The map std::map<key_t, value_t> my_map my_map.begin() struct employee_t { std::string m_name; key value grade_t m_grade; unsigned m_salary; }; key value std::map<unsigned, employee_t> employees; key value employee_t x = employees[get_social_num()]; key value my_map.end() The typical implementation of a map is using a red/black balanced binary tree STL Overview - by Mark Bartosik October 2000
Elements There are some restrictions on the type of objects • Copies must be equivalentThis is normal, but be careful if you have pointers/references as members. • Default construction may be requiredWith a good compiler you’ll only require it if you actually use it. • Do not overload operator&()Cannot use some Microsoft smart pointers. • Containers own the objects they contain (they store by value)This is good but has important implications. STL Overview - by Mark Bartosik October 2000
OwnershipContainers “own” their elements Copies of objects are stored. STL Overview - by Mark Bartosik October 2000
OwnershipAvoid leaks So don’t do this, or your code may leak STL Overview - by Mark Bartosik October 2000
OwnershipUse smart pointers See www.boost.org STL Overview - by Mark Bartosik October 2000
OwnershipShared objects See www.boost.org STL Overview - by Mark Bartosik October 2000
Iterators Iterators behave like pointers, indeed pointers can be used as iterators. All containers have methods begin() and end(). begin() returns an iterator to the first element. end() returns an iterator that points one beyond the end of the last element. typedef std::map<unsigned, employee_t> employees_t;employees_t employees; // copy all employee details to consolefor (employees_t::iterator i = employees.begin(); i != employees.end(); ++i){ std::cout << *i << ‘\n’;} STL Overview - by Mark Bartosik October 2000
Iterators - the glue Iterators are the glue between containers and algorithms. Algorithms act upon a range specified by iterators. Typically this is begin() and end(), but not necessarily. The previous example can be further simplified: typedef std::map<unsigned, employee_t> employees_t;employees_t employees; // copy all employee names to consolestd::copy(employees.begin(), employees.end(), std::ostream_iterator<employee_t>(std::cout, "\n")); To the novice it may not be obvious what this does. There is nothing wrong with using the “for loop”. STL Overview - by Mark Bartosik October 2000
Iterators - like pointers Iterators behave like smart pointers. From the outside there is very little difference between pointers and iterators. However, not all iterators support all operations - maybe more in another talk? The vector supports “random” access iterators. std::vector<T>::iterator i = some_container.begin(); ++i; i++; --i; i--; i->m_member; *i; i+= n; i = i + 5; i == other; i != other; i < other; i > other; i <= other; i >= other; STL Overview - by Mark Bartosik October 2000
One beyond the end? To iteratate through an array, normally we would write:for (int i = 0; i < size; ++i) using pointers this is equivalent to char * one_beyond_end = begin + size; for (char * p = begin; p < one_beyond_end; ++p) but iterators are not pointers, and not all iterators support operator<. However, all iterators do support operator== and operator!=. Thus for generic code we write: for (iterator i = c.begin(); i != c.end(); ++i) and it works for all types of iterators, and with zero length containers. STL Overview - by Mark Bartosik October 2000
Iterators - differences to pointers Apart from the operators supported, differences between iterators and pointers include: • The size of iterators might not be the same as pointers.sizeof(iterator_t) != sizeof(void*);Thus it may not be possible to package iterator into a DWORD for windows calls. For std::list see the non-standard extension _Mynode. • Cannot use CV qualifiers (const or volatile).use const_iterator_t instead of const T * • An array subscript on an iterator refers to an array of iterators. use container[5] or *(iterator+5) instead of pointer[5], • Iterators may be implemented as a class or pointer.void func(& iterator_t);func(get_iterator()); // will fail to compile if iterator_t is a pointer alias. STL Overview - by Mark Bartosik October 2000
Don’t saw off the branch you’re siting on! Don’t invalid an iterator that you’re using! Iterators - some advice STL Overview - by Mark Bartosik October 2000
Another problem my_class{ public: ~my_class(); // How do we write the destructor? . . private: collection_t<object*> m_col;}; • Not following good advice WILL get you into trouble! STL Overview - by Mark Bartosik October 2000
How not to implement my_class::~my_class() { collection_t<object*>::iterator i = m_col.begin(); while (i != m_col.end()) { delete *i; m_col.erase(i); // erase the item (object*), invalidating i ++i; // now the result of incrementing i is undefined } } • Actually erasing the items (object*) in the case of the destructor is not necessary, because they will be destroyed automatically. STL Overview - by Mark Bartosik October 2000
An adequate solution my_class::~my_class() { collection<object*>::iterator i = m_col.begin(); while (i != m_col.end()) { delete *i; m_col.erase(i++); } } Post-increment increments the variable and returns the original value. But this still does not follow the good advice. STL Overview - by Mark Bartosik October 2000
A good solution Use good class design! my_class { . . private: collection<boost::shared_ptr<object> > m_collection; }; • Each object should manage its own resources, not the resources of sub-objects. • Use a smart object or smart pointer. • Think high-level, not low-level. STL Overview - by Mark Bartosik October 2000
Algorithms As we have seen, algorithms act upon ranges of iterators. The existing list of standard algorithms is huge, most with many overloaded variations: adjacent_find · binary_search · copy · copy_backward · count · count_if · equal · equal_range · fill · fill_n · find · find_end · find_first_of · find_if · for_each · generate · generate_n · includes · inplace_merge · iter_swap · lexicographical_compare · lower_bound · make_heap · max · max_element · merge · min · min_element · mismatch · next_permutation · nth_element · partial_sort · partial_sort_copy · partition · pop_heap · prev_permutation · push_heap · random_shuffle · remove · remove_copy · remove_copy_if · remove_if · replace · replace_copy · replace_copy_if · replace_if · reverse · reverse_copy · rotate · rotate_copy · search · search_n · set_difference · set_intersection · set_symmetric_difference · set_union · sort · sort_heap · stable_partition · stable_sort · swap · swap_ranges · transform · unique · unique_copy · upper_bound STL Overview - by Mark Bartosik October 2000
Function Objects Function objects are also called functors. Here the distinction between functions and data become blurred. Functors are objects that define operator(). Typically they act on elements of containers. There are many standard function objects: binary_function · binary_negate · binder1st · binder2nd · divides · equal_to · greater · greater_equal · less · less_equal · logical_and · logical_not · logical_or · mem_fun_t · mem_fun_ref_t · mem_fun1 · mem_fun1_ref_t · minus · modulus · multiplies · negate · not_equal_to · plus · pointer_to_binary_function · pointer_to_unary_function · unary_function · unary_negate STL Overview - by Mark Bartosik October 2000
Function Objects 2 • Function objects are used both as template arguments to containers and to algorithms: std::map<unsigned, employee_t, std::greater> x;std::for_each(x.begin(), x.end(), your_function_object);std::for_each(x.begin(), x.end(), std::mem_func(employee_t::sleep)); • However, function objects are much more powerful than this because they permit data to be bound to functions. Also they enable “functional composition” where by a new function can be created from existing functions without having to actually implement the new function. Functional composition must be used with care to avoid unreadable code.More another time? STL Overview - by Mark Bartosik October 2000
The whole is greater than the sum of the parts! • The beauty of STL is how all the parts can be combined.Containers of almost any type can be acted upon by algorithms.Elements can be acted upon by function objects which can even be combined. • If you avoid a few traps and pit falls…. • You have highly compact and type safe code. • Less code means less bugs. STL Overview - by Mark Bartosik October 2000
Nothing is perfect! STL does have some traps and pit falls. • Containers store copies of objects. • Storing pointers in containers. • Elements are required to have copy constructors, assignment operators, and default constructors. • Modifying containers may invalidate iterators. • The second iterator in a range must be reachable from the first. • Some algorthims like std::remove do not do exactly what you first think - so always read the documentation. • Cannot compile on warning level 4 in VC5 & 6. Need 2000 library. • Compilation errors are cryptic (but better than runtime errors). STL Overview - by Mark Bartosik October 2000
Summary Using STL can improve code by: • Type safety • Reusing library code • Making code simpler • Letting you think and code at a higher level This means less bugs! STL Overview - by Mark Bartosik October 2000
Code Reviews Code reviews are one of the most important ways to maintain software quality. • What does using STL demonstrate ? Hint: Take a look at the Visual Basic and STL code solutions. • Reviewing code like the Visual Basic solution after the fact is a waste of time. It would have been better for the review to have been really early and radically more simple STL solution proposed. STL Overview - by Mark Bartosik October 2000
What next ? • This was just a taster. So maybe HPG should have some more detailed talks - just for programmers? • STL for beginners - maybe 3 or 4 talks • STL traps and pit falls, Advanced STL • General template techniques, Advanced template techniques • C++ class design 1 or 2 talks • Streams 1 or 2 talks • Smart pointers • Formal external training? - see your supervisor • Reading? - next slide • Mentoring? - my cube is open • Changes to the review process? - please discuss STL Overview - by Mark Bartosik October 2000
Recommended readingMy top recommendations on C++ • Scott Meyers • Effective C++ (230 pages) • More Effective C++ (300 pages) • Nicolai Josuttis • The C++ Standard Library (800 pages, including STL) • Stanley Lippman z • C++ Primer (1230 pages, more than just a primer) • Herb Sutter • Exceptional C++ (200 pages, for experts and budding experts only All of these books are very accessible, although some are rather thick. The first 3 are essential reading. STL Overview - by Mark Bartosik October 2000