This book is an essential weapon for the gold medal QA and RD. I learned several chapters every day and enjoyed it every day ~~
int main() { vector<Date> e; copy( istream_iterator<Date>( cin ), istream_iterator<Date>(), back_inserter( e ) ); vector<Date>::iterator first = find( e.begin(), e.end(), "01/01/95" ); vector<Date>::iterator last = find( e.begin(), e.end(), "12/31/95" ); *last = "12/30/95"; copy( first, last, ostream_iterator<Date>( cout, "\n" ) ); e.insert( --e.end(), TodaysDate() ); copy( first, last, ostream_iterator<Date>( cout, "\n" ) );}
If at least four iterators are incorrect, find bug free;
It's not my brother's eyes. I don't even see it at a glance... Wipe it, brother. I still don't believe that a rd cannot do QA! Copy the code. Run GCC and run it. The Code has been compiled...
Okay, do you really want GG? No...
Isn't it testing, boundary, special case, logic overwrite... In the past, a good qamm made me learn something, starting from the boundary!
After finding is complete, I don't know if I can find it. Okay, why is it wrong to solve the reference? Why is an undefined copy error? Directly contributed three bugs...
What about potholes?
Another one cannot be found. Let's look at the answer:
The reason is simple, if a little obscure: on popular implementations of the standard library,Vector <date>: iteratorIs often simply
Date *, And the C ++ language doesn't allow you to modify temporaries of builtin type. For example, the following plain-Jane code is also illegal:
Date* f(); // function that returns a Date* p = --f(); // error, but could be "f() - 1"
The conclusion is not very convincing, but to be honest, I am not capable of writing -- Vec. End...
The summary is as follows:
To summarize: when using iterators, be aware of four main issues.
Valid values: Is the iterator dereferenceable? For example, writing"* E. End ()"Is always a programming error.
Valid lifetimes: Is the iterator still valid when it's being used? Or has it been invalidated by some operation since we obtained it?
Valid ranges: is a pair of iterators a valid range? IsFirstReally before (or equal)Last? Do both really point into the same container?
Illegal builtin Manipulation: for example, is the code trying to modify a temporary of builtin type, as in"-- E. End ()"Above? (Fortunately, the compiler can often catch this kind of mistake for you, and for iterators of class type,
The library author will often choose to allow this sort of thing for syntactic convenience .)
In general, when using the iterator, remember the four days that my brother taught you. That's all right:
- When writing down *, think about this damn thing that looks like a diamond. It may really be like a diamond. You have a lot of cost (core;
- The iterator is an unloyal guy. It will expire when insert and delete operations are executed in almost all containers (list is an exception) (the reason for the failure of the iterator is self-increasing, and the memory is re-applied.
)
- When you need an iterator range, you 'd better make sure that the previous one is really smaller than the next one? Really? Really? Really?
- Do not try to modify a temporary variable that does not exist for you
Iterm2
This can be done if you have any questions. However, well, the solution in the book is quite perfect. Let's code it directly:
struct ci_char_traits : public char_traits<char> // just inherit all the other functions // that we don't need to replace{ static bool eq( char c1, char c2 ) { return toupper(c1) == toupper(c2); } static bool lt( char c1, char c2 ) { return toupper(c1) < toupper(c2); } static int compare( const char* s1, const char* s2, size_t n ) { return memicmp( s1, s2, n ); } // if available on your platform, // otherwise you can roll your own static const char* find( const char* s, int n, char a ) { while( n-- > 0 && toupper(*s) != toupper(a) ) { ++s; } return n >= 0 ? s : 0; }};And finally, the key that brings it all together:typedef basic_string<char, ci_char_traits> ci_string;
Use traits directly ~
In the next section, is there a "Is it safe to use inheritance? "Question, that's a good question!
(1) The proper uses (and improper abuses) of inheritance; knows why it is used and why it is not inherited;
(2) the implications of the fact that there are only static members; use static functions (conform to the is-a or work-like-a model ),
(3) The fact thatChar_traitsObjects are never used polymorphically. No polymorphism is used to ensure its security.
Note: The cause of iterator failure (from http://blog.csdn.net/zhongjiekangping/article/details/5624922 ):
Several cases of invalidation of the vector iterator: 1. When an element is inserted (push_back), The iterator returned by the end operation will certainly become invalid. 2. When an element is inserted (push_back), the return value of capacity is different from that before the element is inserted. Then, the entire container needs to be reloaded, And the iterator returned by the first and end operations will become invalid. 3. After the delete operation (erase, pop_back) is performed, all the iterators pointing to the delete vertex are invalid. All the iterators pointing to the elements behind the delete vertex are also invalid.
Deque iterator invalidation: This is the limitation in C ++ Primer: 1. inserting elements in the first or end of the deque container will not invalidate any iterator. 2. Deleting an element at its header or tail will only invalidate the iterator pointing to the deleted element. 3. The insert and delete operations at any other location of the deque container will invalidate all iterators pointing to the container element. However, I found in vs2005 that the first one was not satisfied. Why? Wait for the STL to go deep and then understand it slowly!
Only list iterators seem to be ineffective in rare cases. Maybe when you delete the node, the iterator pointing to the deleted node will become invalid. Nothing else has been found.