2

The following code results in "0004567" on clang++-7

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    ostringstream oss{"1234567"};
    oss << "000";
    cout << oss.str() << endl;
}

Now is this correct STL implementation?

I can't think of how is it useful to initialize with a string that will be overwritten...

gatopeich
  • 3,287
  • 31
  • 26
  • 4
    It's just as useful as opening a non-empty file with `std::ofstream`. Try `ostringstream oss{"1234567", std::ios_base::app};` . Or `std::ios_base::ate` – Igor Tandetnik Jun 06 '20 at 21:26
  • Well the point of stringstreams is that they are not files. No point in emulating file behavior in spite of usability. ::ate is the sensible default here. – gatopeich Jun 08 '20 at 11:20

1 Answers1

3

@IgorTandetnik gave your a solution - to add std::ios_base::app std::ostringstream constructor argument.

However, there is no benefit in passing the initial string (and only a string) into constructor. The argument still gets copied, similar to what oss << "1234567"; does, but it requires providing an extra constructor argument which risks introducing a programming error (and it does in your code).

I suggest keeping it simple:

ostringstream oss;
oss << "1234567";
oss << "000";
// alternatively, just do oss << "1234567000";
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • Thanks. Now I wonder why ios_base::app is not the default mode, since the current one is not usable. The STL is still frustratingly unfriendly after so many updates to the standard... – gatopeich Jun 07 '20 at 09:50
  • 1
    @gatopeich IOStreams are often criticised for it poor design. Rightly, IMO. – Maxim Egorushkin Jun 07 '20 at 10:48
  • Indeed, @Maxim. It looks like the main design goal of IOStreams was "to look very different to any other language specially C". The rest is details – gatopeich Jun 08 '20 at 11:24