3

Why does the following code...

#include <iostream>
#include <sstream>
#include <utility>

int main()
{
    std::pair<std::string, std::string> pair1((std::ostringstream().flush() << "hello").str(), (std::ostringstream().flush() << "world").str());
    return 0;
}

... generate the compiler error...

>g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:7: error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’
main.cpp:7: error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’

...whereas the code below does not generate any compiler error?

#include <iostream>
#include <sstream>
#include <utility>

int main()
{
    std::ostringstream oss1;
    std::ostringstream oss2;
    oss1 << "hello";
    oss2 << "world";
    std::pair<std::string, std::string> pair1(oss1.str(), oss2.str());
    return 0;
}

If anyone can advise how to, I would ideally like to pull off a "one-line" creation and population of my std::pair, as I'm attempting to do in the first code block. Thank you.

StoneThrow
  • 5,314
  • 4
  • 44
  • 86

1 Answers1

1

The operator<< function you're using to write the string literals takes a basic_ostream& and returns a basic_ostream&. But str is a member of basic_ostringstream, so you cannot invoke it on a basic_ostream&.

You could cast the return value, and your code would compile

static_cast<std::ostringstream&>(std::ostringstream().flush() << "hello")).str()

Also, since flushing a default constructed stringstream is pointless, you should get rid of that.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Thank you. Your answer, though, gives me concern about downcasting a basic_ostream to a basic_ostringstream. Is this considered safe because the basic_ostream& returned by operator<< is actually the very same rvalue ostringstream upon which it is invoked? – StoneThrow Jan 15 '16 at 01:05
  • @StoneThrow The returned `ostream&` refers to the base class instance of the `ostringstream` instance you constructed, so it's absolutely safe to cast it back to the original type. – Praetorian Jan 15 '16 at 01:08