Title: STL Overview
1STL Overview
- Intended audience
- C/C programmers not already expert in STL.
- Visual Basic and Java programmers - see what
youre missing! - Managers - see why should your staff be competent
in STL. - Others either youre here for the cookies, or
youre in the wrong room?
Please take your seats, and fasten your seat
belts. Our flight will last approximately 1 hour,
well be flying over STL at mach 2, at an
altitude of 70,000 feet.
HANG ON!
2Audience
- Non C programmers 40
- C programmers but without STL 35
- Experienced C/STL programmers 10
- Managers lt10
- Others lt10
- I hope that there is something here for
all.Feel free to ask questions.
3The Goal
- Qgt 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?
4What is STL ?
- Standard Template Library
- So its 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.
5Where is STL ?
- STL is part of the C runtime library
- C runtime library (CRT)
- time(), strcpy(), strstr()
- streams
- stdistreamltgt, ostream (vendors support new and
old versions) - strings
- stdstring, stdwstring, stdbasic_stringltgt
- STL
- stdvectorltgt, stdmapltgt, stdfind,
stdtransform - misc
- stdexception, stdlocale
6Wheres 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.
7Done 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 wont you find!!
8Pseudo 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!
9STL - the concept
less
bind1st
find
bind2nd
copy
int, long, string, your_class_t, etc.
remove
count_if
transform
vectorltgt
listltgt
dequeltgt
algorithms
types
mapltgt
multimapltgt
function objects
setltgt
multisetltgt
valarrayltgt
many more
streamsltgt
algorithms
hashtablesltgt
function objects
Glued together
containers
with "iterators"
utility_of_STL types x containers x (algorithms
functors)
sizeof(STL) containers algorithms functors
10Solutions 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.
11Reuse
- 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
youll 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
12Type safety the problem
- Example problemQgt 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.
13Templates - the solution
- Microsofts 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. - templatelttypename Tgt void print_all(const T
col) stdcopy(col.begin(), col.end(), stdos
tream_iteratorltTvalue_typegt(stdcout, ,))
14STL containers
- Unsorted containers
- stdvectorltTgt dynamic array prefer this to
char p new charn - stdlistltTgt doubly linked list
- stddequeltTgt like a vector but you can insert
at the front and back - Sorted containers
- stdsetltTgt a sorted set of unique values
- stdmultisetltTgt a sorted set of values, there
may be duplicates - Sorted associative containers
- stdmapltkey_t, value_tgt an associative array,
like a database table with a unique key field
and one other field - stdmultimapltkey_t, value_tgt like map, but the
record keys do not need to be unique
15Other containers
- The C runtime library
- stdstringltTgt a string of characters (wide or
narrow) - stdvalarrayltTgt used for efficient vector
processing mathematics - Streams?stdistream, stdostream,
stdiostream - AdaptersThere are also STL adapters that are
wrappers on the STL containersstdstack,
stdqueue (FIFO), stdpriority_queue. - Non standardHash tables
16The vector
stdvectorltTgt my_vector
my_vector.begin()
my_vector.end()
T
T
T
T
my_vector.push_back(t)
17The 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 , !, lt, gt,
lt, gt, - There is a lot of useful functionality here.
18The list
stdlistltTgt my_list
my_list.begin()
T
T
T
my_list.end()
19The map
stdmapltkey_t, value_tgt my_map
my_map.begin()
struct employee_t
stdstring m_name
key
value
grade_t m_grade
unsigned m_salary
key
value
stdmapltunsigned, employee_tgt employees
key
value
employee_t x employeesget_social_num()
key
value
my_map.end()
The typical implementation of a map is using a
red/black balanced binary tree
20Elements
- 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 youll 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.
21OwnershipContainers own their elements
Copies of objects are stored.
22OwnershipAvoid leaks
So dont do this, or your code may leak
23OwnershipUse smart pointers
See www.boost.org
24OwnershipShared objects
See www.boost.org
25Iterators
- 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 stdmapltunsigned, employee_tgt
employees_temployees_t employees - // copy all employee details to consolefor
(employees_titerator i employees.begin()
i ! employees.end() i)
stdcout ltlt i ltlt \n
26Iterators - 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 stdmapltunsigned, employee_tgt
employees_temployees_t employees - // copy all employee names to consolestdcopy(e
mployees.begin(), employees.end(),
stdostream_iteratorltemployee_tgt(stdcout,
"\n")) - To the novice it may not be obvious what this
does. There is nothing wrong with using the for
loop.
27Iterators - 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.
- stdvectorltTgtiterator i some_container.begin
() - i i
- --i i--
- i-gtm_member i
- i n i i 5
- i other i ! other
- i lt other i gt other i lt other i gt other
28One beyond the end?
- To iteratate through an array, normally we would
write for (int i 0 i lt size i) - using pointers this is equivalent to char
one_beyond_end begin size for (char p
begin p lt one_beyond_end p) - but iterators are not pointers, and not all
iterators support operatorlt. 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.
29Iterators - 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 stdlist 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 container5 or
(iterator5) instead of pointer5, - Iterators may be implemented as a class or
pointer.void func( iterator_t)func(get_iterato
r()) // will fail to compile if iterator_t is a
pointer alias.
30Iterators - some advice
- Dont saw off the branch youre siting on!
- Dont invalid an iterator that youre using!
31Another problem
- my_class public my_class() //
How do we write the destructor? .
. private collection_tltobjectgt
m_col - Not following good advice WILL get you into
trouble!
32How not to implement
- my_classmy_class()
-
- collection_tltobjectgtiterator 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.
33An adequate solution
- my_classmy_class()
-
- collectionltobjectgtiterator 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.
34A good solution
- Use good class design!
- my_class
-
- .
- .
- private
- collectionltboostshared_ptrltobjectgt gt
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.
35Algorithms
- 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
36Function 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
37Function Objects 2
- Function objects are used both as template
arguments to containers and to algorithms - stdmapltunsigned, employee_t, stdgreatergt
xstdfor_each(x.begin(), x.end(),
your_function_object)stdfor_each(x.begin(),
x.end(), stdmem_func(employee_tsleep)) - 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?
38The 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.
39Nothing 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 stdremove 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).
40Summary
- 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!
41Code 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.
42What 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
43Recommended 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.