I came across a subtle bug a couple of days ago where the code looked something like this:
ostringstream ss;
int anInt( 7 );
ss << anInt << "HABITS";
ss << ends;
string theWholeLot = ss.str();
The problem was that the ends
was sticking a '\0' into the ostringstream
so theWholeLot
actually looked like "7HABITS\0"
(i.e. a null at the end)
Now this hadn't shown up because theWholeLot
was then being used to take the const char *
portion using string::c_str()
That meant that the null was masked as it became just a delimiter. However, when this changed to use strings throughout, the null suddenly meant something and comparisons such as:
if ( theWholeLot == "7HABITS" )
would fail. This got me thinking: Presumably the reason for ends
is a throwback to the days of ostrstream
when the stream was not normally terminated with a null and had to be so that str()
(which then cast out not a string
but a char *
) would work correctly.
However, now that it's not possible to cast out a char *
from a ostringstream
, using ends
is not only superfluous, but potentially dangerous and I'm considering removing them all from my clients code.
Can anyone see an obvious reason to use ends
in a std::string
only environment?
You've essentially answered your own question is as much detail that's needed. I certainly can't think of any reason to use std::ends
when std::string
and std::stringstream
handle all that for you.
So, to answer your question explicitly, no, there is no reason to use std::ends
in a std::string
only environment.
There are some APIs that expect a "string array" with multiple zero terminated strings, a double zero to mark the end. Raymond Chang just recently blogged about it, most of all to demonstrate how often that this gets fumbled.
来源:https://stackoverflow.com/questions/2338377/what-use-is-there-for-ends-these-days