views:

68

answers:

2
class mystream : public std::stringstream
{
public:
    void write_something()
    {
        this << "something";
    }
};

This results in the following two compile errors on VC++10:

error C2297: '<<' : illegal, right operand has type 'const char [10]'
error C2296: '<<' : illegal, left operand has type 'mystream *const '

Judging from the second one, this is because what this points at can't be changed, but the << operator does (or at least is declared as if it does). Correct?

Is there some other way I can still use the << and >> operators on this?

+8  A: 

mystream *const means that this is a constant pointer to a non-constant object. The problem is that you're trying to stream-insert into a pointer -- you must insert into a stream. Try the following.

*this << "something";
avakar
Duh, showing my C# side... Thank you.
romkyns
+1  A: 

The destructor of an stringstream (actually a basic_stringstream<char> ) is not virtual, and as all classes from the C++ SL, you're not really supposed to derive from them...

Depending on what exactly you want to do, I will tell you to prefer composition to inheritance, and maybe create your own templated << and >> operators that will use your underlying stream. Or maybe it is wiser not to use a stringstream as a member.

Nikko
I got my inspiration from http://stackoverflow.com/questions/2196155/is-there-anyway-to-write-the-following-as-a-c-macro which has enough votes for me to perceive such derivation as acceptable. I've also found http://stackoverflow.com/questions/922248/is-there-any-real-risk-to-deriving-from-the-c-stl-containers following your advice though.
romkyns
Because this clever trick does not really work and you can have some problems?? :) try `my_macro << std::string("surprise")`
Nikko
Nikko is right about my_macro. It creates an anonymous instance of my_stream, this instance will only work for operator << methods, and not for operator << functions. The code will compile but you can produce different output on different platforms.
iain
Regarding the destructor not being virtual. This would only be a problem if you or anyone else tried to destroy my_stream virtaly. That is std::stringstream * stream = new mystream; (*stream) << "stuff"; delete stream;This would not work, and there is now way you can prevent this type of code being written. However documenting that my_stream should never be deleted polymorphically would prevent this then you code would be safe, except for the fact that global functions will not work with the macro.
iain
It is safer to use delegation for this, see my answer to a similar question that gets round the `my_macro << std::string("surprise")` problem http://stackoverflow.com/questions/1328568/custom-stream-manipulator-for-class/1329092#1329092
iain
@iain It does not compile with gcc 4.3
Nikko