Compiler oddness with << overload

C

cedarmillxing215

The oddness is on the last line of code. This is stripped down as far
as I could figure, and I provide several similar examples that work as
expected. I have no idea whether this is a compiler bug or my not
understanding how the << overload is chosen.

-Chris

--------------------

#include <iostream>
#include <sstream>

ostringstream get()
{
return ostringstream();
}

class my_ostringstream : public ostringstream
{
public:
static my_ostringstream get() { return my_ostringstream(); }
~my_ostringstream() { cout << str() << endl; }
};



int main(int argc, char * argv[])
{
ostringstream var1;
var1 << "text 1";
cout << var1.str() << endl; // Output: text 1

ostringstream var2("text 2");
cout << var2.str() << endl; // Output: text 2

ostringstream var3 = get();
var3 << "text 3";
cout << var3.str() << endl; // Output: text 3

{
my_ostringstream var4;
var4 << "text 4";
} // Output: text 4

{
my_ostringstream var5 = my_ostringstream::get();
var5 << "text 5";
} // Output: text 5

{
my_ostringstream::get() << "text 6"; // WTF, seems to be treated
as a void *
} // Output: 00417800
}
 
C

cedarmillxing215

* (e-mail address removed):


In order to make the below code work you need to either prefix each name from
the standard library with "std::", or emply a "using namespace std;" directive.
Yes, using namespace std, sorry, cut & paste error.
ostringstream get()
{
  return ostringstream();
}
class my_ostringstream : public ostringstream
{
public:
  static my_ostringstream get() { return my_ostringstream(); }
  ~my_ostringstream() { cout << str() << endl; }
};
int main(int argc, char * argv[])
{
  ostringstream var1;
  var1 << "text 1";
  cout << var1.str() << endl;  // Output: text 1
  ostringstream var2("text 2");
  cout << var2.str() << endl;  // Output: text 2
  ostringstream var3 = get();
  var3 << "text 3";
  cout << var3.str() << endl;  // Output: text 3
  {
    my_ostringstream var4;
    var4 << "text 4";
  }  // Output: text 4
  {
    my_ostringstream var5 = my_ostringstream::get();
    var5 << "text 5";
  }  // Output: text 5
  {
    my_ostringstream::get() << "text 6"; // WTF, seems to be treated
as a void *
  }  // Output: 00417800
}

operator<< for argument 'char const*' is not a member function. For the
namespace level operator<< a temporary (rvalue) can't bind to reference to
non-const formal argument. The member operator<< with 'void const*' is selected.

Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Thank you Alf, that helps me more forward a little. It is still very
confusing though.

The void * version
ostream & operator<<(ostream &, const void *)
is an inherited member while the char * version
ostream & operator<<(ostream &, const char *)
is a standalone function (a friend?).
But why does this mean that the void * overload is selected only in
case #6? It seems that either function could have been called. Here
are two clarifying examples I tried after your help.

// initialized setup as above

{
my_ostringstream::get() << "text 6" << " & 7";
} // Output: 00417810 & 7

{
operator<<(my_ostringstream::get(), "text 8") << " & 9";
} // Output: text 8 & 9

-Chris
 
J

James Kanze

* (e-mail address removed):
Quoting myself, "a temporary (rvalue) can't bind to reference
to non-const formal argument".

But you can call a non-const member function on a temporary.
Which is why << void* is found, but << char* not.
This applies to the stream object.

It's probably too late for this round, but I wonder if it
wouldn't be a good idea to require all operator<< to be
non-members. At least the overload set would be consistent.
(IMHO, it would be an even better idea to make operator<< a
template member, with all of the actual instances
specializations. Because it does make sense to do things like
"std::eek:stringstream() << ...". But of course, doing that would
break considerable code: probably every C++ application in
existance, in fact.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,138
Messages
2,570,804
Members
47,349
Latest member
jojonoy597

Latest Threads

Top