3

I have the following macro.

#define STRING_STREAM( data )       \
    ( ( (std::ostringstream&)       \
        ( std::ostringstream( ).seekp( 0, std::ios_base::cur ) << data ) ).str( ) )

I am trying to overload << for an enum:

std::ostringstream& operator<<( std::ostringstream& oStrStream, TestEnum& testEnum )
{
    oStrStream << "TestEnum";
    return oStrStream;
}

When I call STRING_STREAM( testEnum ), it doesn't use the overloaded <<. It prints enums number value.

ssk
  • 9,045
  • 26
  • 96
  • 169
  • I suggest you look at boost::lexical_cast: http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast.html – robert May 18 '12 at 20:08
  • 1
    Note that you are asking for a mutable reference to an `enum`. – K-ballo May 18 '12 at 20:10
  • 2
    Why are you overloading the `operator<<` for an `ostringstream` instead of an `ostream`? – robert May 18 '12 at 20:11
  • What exactly do you want the output to be? The `enum`'s identifiers? – dirkgently May 18 '12 at 20:14
  • @robert I need to convert the ostringstream to std::string. That's why I am using ostringstream instead of ostream. – ssk May 18 '12 at 20:54
  • 1
    I'd be REALLY careful not returning `ostream&`. See http://stackoverflow.com/questions/10386702/custom-class-ostringstream-output-error for why. The marked answer says how this can get you into trouble. – Kevin Anderson May 18 '12 at 21:07
  • I changed to ostream and added const&, it works fine. – ssk May 18 '12 at 21:15
  • @Santhosh why don't you change your comment to an answer? That's allowed - encouraged even. – Alan Stokes May 19 '12 at 16:37

2 Answers2

2
std::ostream& operator<<( std::ostream& oStrStream, const TestEnum testEnum )
{
    oStrStream << "TestEnum";
    return oStrStream;
}
ssk
  • 9,045
  • 26
  • 96
  • 169
  • 1
    If it is just an enum it's probably better to pass it by value not reference: `std::ostream& operator<<( std::ostream& oStrStream, TestEnum testEnum ) { ... }` – Alan Stokes May 20 '12 at 19:07
0

The problem is that the overloaded << operator is expecting an argument of..

new ostringstream() 

but you're giving it the argument..

ostringstream()

This is not being matched by the overloaded function.

In my example, I used auto_ptr to automatically deallocate the ostringstream after it goes out of scope. This allows us to use a macro to perform our function without memory leaks.

#include<sstream>
#include<iostream>
#define STRING_STREAM( data )                                                  \
   ((ostringstream&)( *( auto_ptr<ostringstream>(new ostringstream()) ) << data)).str()

using namespace std;

enum TestEnum { ALPHA, BETA };

ostringstream& operator<<( ostringstream& oss, TestEnum testEnum ){
    oss << "TestEnum";
    return oss;
}
int main(){
    cout << STRING_STREAM( ALPHA ) << endl;
}
Jared Sealey
  • 324
  • 1
  • 10
  • 1
    Why on earth are you allocating a temporary on the heap? – Alan Stokes May 19 '12 at 15:10
  • The overloaded function would only accept a dynamically allocated ostringstream. I added the smart pointer to take care of the memory after it goes out of scope. – Jared Sealey May 19 '12 at 15:16
  • The function takes the stream by reference. The stream does *not* need to be on the heap. – Alan Stokes May 19 '12 at 16:35
  • I would agree with you, but for this overloaded operator it would not work without being on the heap. Please show me how the macro would look if it was working the way you mention. It would not work any other way for me. – Jared Sealey May 19 '12 at 17:18