Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does writing into temporary string stream object only print object addresses?

Tags:

The following snippet is simplified version of a logger that I use. It extends std::ostringstream and can be filled using the <<-operator. Upon destruction all content is written to std::cout.

Writing (<<) directly into a temporary object, Logger(), I would expect it to print that input, however, it only prints the address of something on std::cout. When writing into a reference of a temporary object, Logger().stream(), works as expected.

Why is that happening?

Btw, this behavior only occurs in C++98-land (ideone), which I have to use. With C++11 (coliru) and C++14 (ideone) both call variants work as expected. What's different in C++11/14?

#include <iostream> #include <sstream>  class Logger : public std::ostringstream { public:     ~Logger()     {         std::cout << this->str() << std::endl;     }      Logger& stream()     {         return *this;     } };  int main( int argc, char ** argv ) {     // 1.     // Prints an address, e.g. 0x106e89d5c.     Logger() << "foo";      // 2.     // Works as expected.     Logger().stream() << "foo";      // What is the difference between 1. and 2.?      return 0; } 
like image 696
nils Avatar asked Apr 24 '15 23:04

nils


1 Answers

The operator<< that handles insertion of const char * is a non-member template:

template< class Traits >  basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>& os, const char* s); 

It takes its stream by non-const (lvalue) reference, which does not bind to temporaries.

In C++98/03, the best viable function is the member operator<<(const void *), which prints an address.

In C++11 and later, the library supplies a special operator<< for rvalue streams:

template< class CharT, class Traits, class T > basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,                                              const T& value ); 

which does os << value and returns os, essentially performing the output operation on an lvalue stream.

like image 52
T.C. Avatar answered Oct 03 '22 03:10

T.C.