What use is there for 'ends' these days?

2020-04-02 07:39发布

问题:

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?

回答1:

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.



回答2:

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.