A common mistake when using STL object and algorithm is to assume implementation details. For example when we use the ostringstream class, it may be easy to assume that the object contain a string member and that the str() function must return that data. If we just think like that and don’t look deeper at the str() function declaration, we can write the following code and suppose that the output will be correct.
std::ostringstream os; os << 1234 << std::endl;
std::copy(os.str().begin(), os.str().end(), std::back_inserter(outputContainer));
But it will not be correct and you cannot rely on the compiler to detect the issue because the syntax is correct. We pass 2 iterator on a string, but the issue is that they are not iterator on the ‘same’ string.
The function declaration of str() is:
string str() const;
and it means 2 things:
- the ostringstream object will not be modified by the call
- the returned string object is an lvalue (return by copy).
you can also read that post in which that trap is fully detailed….
But to summarize, every call to str() return a different string so the the begin and end iterator we provided in the previous piece of code aren’t related to the same string.
The only correct way to manage that situation is to create a copy of the string like below or to use your own ostringstream version like describe in that post.
std::ostringstream os; os << 1234 << std::endl;
std::string acpy = os.str();
std::copy(acpy.begin(), acpy.end(), std::back_inserter(outputContainer));
The conclusion is that when you use a STL object or an algorithm take attention at the declaration because if you don’t you may fall in some traps.