Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: invalid operands to binary expression ostream and ostringstream

Tags:

c++11

Why is the following no longer a valid C++11 code (compiles fine as C++98):

#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os;
  os << "Hello World!";
  std::cout << os << std::endl;
  return 0;
}

for reference here is (truncated) what I get with clang:

$ clang++ -stdlib=libc++ -std=c++11 t.cxx
t.cxx:8:13: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::ostringstream' (aka 'basic_ostringstream<char>'))
  std::cout << os << std::endl;
  ~~~~~~~~~ ^  ~~
/usr/include/c++/v1/ostream:190:20: note: candidate function not viable: no known conversion from 'std::ostringstream' (aka 'basic_ostringstream<char>') to
      'const void *' for 1st argument; take the address of the argument with &
    basic_ostream& operator<<(const void* __p);
like image 608
malat Avatar asked Aug 26 '13 16:08

malat


2 Answers

It may compile in C++03, but it doesn't make one bit of sense. C++11 just used a new feature to make the code that makes no sense, not compile in the first place.

See, std::ostringstream (and all other stream classes) used to have an implicit conversion to void*. What this returned wasn't a proper pointer, though; it was just either null if the stream was in an invalid state, or not null if it was valid. That's what allowed you to write e.g.

std::ofstream ofs("filename");
if (ofs) ...

However, the conversion to void* was problematic, because you do other stupid stuff with a void*. Even before C++11, the safe-bool idiom was discovered that would have been better. But for C++11, explicit conversions were added, which were a lot better. So for C++11, the conversion to void* was replaced by an explicit conversion to bool, which allows the same useful code to compile without allowing useless code (such as yours) to compile. And that's why the code doesn't work anymore in C++11.

This is not a bad thing. It's a good thing. You discovered that the code you had doesn't make sense, without the pains of it misbehaving at runtime.

like image 155
Sebastian Redl Avatar answered Oct 17 '22 06:10

Sebastian Redl


The code that does what you intended to do is as following:

#include <sstream>
#include <iostream>

int main()
{
  std::ostringstream os;
  os << "Hello World!";
  std::cout << os.str() << std::endl;
  return 0;
}
like image 25
Andrew Tomazos Avatar answered Oct 17 '22 07:10

Andrew Tomazos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!