String streams and operator << misbehaving

A

Adam Nielsen

Hi everyone,

Following advice previously given in this group, I've created a function
that I'm using to "inline" the creation of a string. Regardless of what
you think of my method, I'm confused as to why the operator <<
overloading seems to be selecting the wrong function.

If you look at the example program below, it should print this:

The string is 'Five == 5'

However the first variable in the createString() parameter is always
treated as an integer or pointer, instead of its native type - hence you
end up with something like this:

The string is '0x804b485 == 5'

Could someone please enlighten me as to what's causing this behaviour?
Even if I pass "std::ios::dec" as the first parameter, this results in a
"2" being printed, which I find very unusual.

Thanks,
Adam.


#include <sstream>
#include <stdio.h>

inline std::string _createString(const std::basic_ostream<char,
std::char_traits<char> > &sstr)
throw ()
{
return static_cast<const std::eek:stringstream&>(sstr).str();
}

#define createString(a) _createString(std::eek:stringstream() << a)

int main(void)
{
std::string strTest = createString("Five" << " == " << 5);

printf("The string is '%s'\n", strTest.c_str());
return 0;
}
 
S

Stuart Redmann

Adam said:
Hi everyone,

[Snipped description of the problem: OP is asking why the wrong operator<< is
called on the string stream.]
#include <sstream>
#include <stdio.h>

inline std::string _createString(const std::basic_ostream<char,
std::char_traits<char> > &sstr)
throw ()
{
return static_cast<const std::eek:stringstream&>(sstr).str();
}

#define createString(a) _createString(std::eek:stringstream() << a)

int main(void)
{
std::string strTest = createString("Five" << " == " << 5);

printf("The string is '%s'\n", strTest.c_str());
return 0;
}

This question comes up once in three months (maybe we should put it in the FAQ?)
The strange behaviour you are experiencing is due to the fact that the ostream
object you are putting your code into is a temporary object. For some reasons,
C++ only lets you call _member functions_ on temporary objects.

Since std::eek:stream provides only a limited set of methods for printing very
basic types (the overloads for your own types are non-member functions), it will
choose std::eek:stream::eek:perator<<(const void*).

#include <sstream>
#include <memory>
#include <stdio.h>

std::auto_ptr<std::eek:stringstream> GetStream ()
{
return std::auto_ptr<std::eek:stringstream> (new std::eek:stringstream);
}

#define createString(a) \
(static_cast<const std::eek:stringstream&>(((*GetStream ().get()) << a)).str ())

int main(void)
{
std::string strTest = createString("Five" << " == " << 5);

printf("The string is '%s'\n", strTest.c_str());
return 0;
}

Regards,
Stuart
 
A

Adam Nielsen

The strange behaviour you are experiencing is due to the fact that the
ostream object you are putting your code into is a temporary object. For
some reasons, C++ only lets you call _member functions_ on temporary
objects.

Since std::eek:stream provides only a limited set of methods for printing
very basic types (the overloads for your own types are non-member
functions), it will choose std::eek:stream::eek:perator<<(const void*).

Ah, that makes sense. Thanks for the explanation! I'm sure there's a
logical reason why that behaviour is intentional. At any rate your
solution works quite nicely!

Cheers,
Adam.
 

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
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top