views:

306

answers:

4

I'd like to do this:

MyClass mc = MyClass("Some string" << anotherString);

Thanks for your answers, I have decided to re-write this question based on what you've told me, as it's gotten a little messy. Eventually, I read C++ format macro / inline ostringstream, and decided to use a macro, as it's not really possible to do this using a constructor. Some answers my no longer be relevant.

Now, what I can actually, do is:

MY_CLASS("Some string" << anotherString << " more string!");

Using this macro:

#include <sstream>

#define MY_CLASS(stream) \
MyClass( ( dynamic_cast<std::ostringstream &> ( \
    std::ostringstream() . seekp( 0, std::ios_base::cur ) << stream ) \
) . str() )

Where the MyClass constructor takes a string:

MyClass::MyClass(string s) { /* ... */ }
+2  A: 

Your compile error looks like have included

<iosfwd>

in your class's header file, but you haven't included

<sstream>

in the cxx file.

David Norman
This isn't going to help since "Some string" << anotherString doesn't create a string.
Eclipse
Thanks, this post was relevant before I restructured the question - and helped it a lot.
nbolton
+1  A: 

I think you should look at this question for some hints as to what will be required to get the behavior you want.

This sort of thing seems to a bit difficult.

David Norman
+1  A: 

The << operator returns an ostream &, not a streamstream &, so you'd have to do a dynamic cast:

MyClass::MyClass(ostream &stream)
{
    string myString = dynamic_cast<stringstream &>(stream.str());
}

stringstream s;
MyClass *mc = new MyClass(s << "Some string" << anotherString);

But really that's a terrible thing to do. Try something like this:

class Streamer
{
stringstream stream;
public:
    template <class T>
    Streamer &operator <<(const T &object) { stream << object; return *this;}
    operator string() { return stream.str(); }
};    

class MyClass
{
public:
    MyClass(const string &s) : MyString(s) {}
    string MyString;
};

int main()
{
    MyClass myClass(Streamer() << "something" << "world");
    cout << myClass.MyString;
}
Eclipse
Unless, as I did, you force a stringstream to be constructed.
Eclipse
Yes, I think that's the most sensible approach. Of coutrse, he probably doesn't need to create the MyClass instance with new, either.
anon
Is this more elegant than using a macro?
nbolton
Define elegant..
Eclipse
Good point, I mean elegant as in: Implementation is clearer / easier.
nbolton
Clearer would just be to pass in a string in the first place: MyClass myClass(string("something") + "other thing");
Eclipse
+5  A: 

redesign your solution. if your c-tor needed string it should accept string.
also in this and similar cases will better if your constructor will accept const reference.

no matching function for call to ‘MyClass(std::basic_ostream <..>&)

error happened because operator<< defined for and returns std::basic_ostream not std::stringstream object. ofcourse you could use

dynamic_cast< const std::stringstream& >( s << "hello" << "world" )

but your team lead could fire you for this code:)

BTW:

MyClass mc = MyClass("Some string" << anotherString);

could be rewriten as

MyClass mc("Some string" << anotherString);
bb
I've tried using ostream, but I get another error...
nbolton
i've wrote solution =)
bb
Thanks, I didn't know about the shorthand init.
nbolton
bb