string streams

N

Nick Keighley

Hi,

I want to store the representation of a class (called Thing in
this post) in a string. The class provides no access to Thing's
internal components but does provide an operator<<(). Defined
like this:-

friend ostream & operator<<(ostream &stream,const Thing &right);

So I thought: I'll use stringstream


#include <string>
#include <sstream>

Thing thing(...); // initialised somehow
std::eek:stringstream id;
id << string("Thing: ") << thing;
// then id.str() is the string I want.

Unfortunatly, this doesn't work. The compiler says there is no
operator<< which takes a right-hand operand of Thing. Is (as I
assumed) ostringstream derived from ostring? Even if it is, presumably
this isn't supposed to work. Is there a way to do this? If I have to
modify Thing I might just give it a get() method for its internal value
(it's an integer...).


--
Nick Keighley

"It startled him even more when just after he was awarded the
Galactic Institute's Prize for Extreme Cleverness he got lynched
by a rampaging mob of respectable physicists who had finally
realized that the one thing they really couldn't stand was a
smart-ass."
Douglas Adams, The Hitchhiker's Guide to the Galaxy (1979)
 
V

Victor Bazarov

Nick said:
I want to store the representation of a class (called Thing in
this post) in a string. The class provides no access to Thing's
internal components but does provide an operator<<(). Defined
like this:-

friend ostream & operator<<(ostream &stream,const Thing &right);

So I thought: I'll use stringstream


#include <string>
#include <sstream>

Thing thing(...); // initialised somehow
std::eek:stringstream id;
id << string("Thing: ") << thing;
// then id.str() is the string I want.

Unfortunatly, this doesn't work. The compiler says there is no
operator<< which takes a right-hand operand of Thing. Is (as I
assumed) ostringstream derived from ostring? Even if it is, presumably
this isn't supposed to work. Is there a way to do this? If I have to
modify Thing I might just give it a get() method for its internal value
(it's an integer...).

This is covered in the FAQ 5.8.

V
 
L

Larry I Smith

Nick said:
Hi,

I want to store the representation of a class (called Thing in
this post) in a string. The class provides no access to Thing's
internal components but does provide an operator<<(). Defined
like this:-

friend ostream & operator<<(ostream &stream,const Thing &right);

So I thought: I'll use stringstream


#include <string>
#include <sstream>

Thing thing(...); // initialised somehow
std::eek:stringstream id;
id << string("Thing: ") << thing;
// then id.str() is the string I want.

Unfortunatly, this doesn't work. The compiler says there is no
operator<< which takes a right-hand operand of Thing. Is (as I
assumed) ostringstream derived from ostring? Even if it is, presumably
this isn't supposed to work. Is there a way to do this? If I have to
modify Thing I might just give it a get() method for its internal value
(it's an integer...).


--
Nick Keighley

"It startled him even more when just after he was awarded the
Galactic Institute's Prize for Extreme Cleverness he got lynched
by a rampaging mob of respectable physicists who had finally
realized that the one thing they really couldn't stand was a
smart-ass."
Douglas Adams, The Hitchhiker's Guide to the Galaxy (1979)

Either of these should work IF 'Thing' really does have an
operator<<().

id << std::string("Thing: ") << thing;
-or-
id << "Thing: " << thing;

Then id.str() can be used to get access to the resulting string.

Perhaps 'Thing' does not have an operator<<() -or- perhaps
it is in a namespace and needs to have the name fully qualified
-or- perhaps you're not including the header which defines the
operator<<() for 'Thing' -or- perhaps you are not linking with
the module/library that contains the compiled code for 'Thing',
-or- perhaps ....

Do you get the idea? As Victor pointed out, there's not enough
information to provide an answer.

Larry
 
N

Nick Keighley

Victor said:
Nick Keighley wrote:


This is covered in the FAQ 5.8.

deepest apologies. I was more checking to make sure what I was trying
to
do was even plausible. Checking a reference book showed it was. Writing

the 10 line program I should have written in the first place:-

#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>

using namespace std;

class ThingId
{
public:
ThingId (int ident = 0): id_(ident) {}
friend ostream & operator<< (ostream &stream,const ThingId &right);

private:
int id_;
};

ostream& operator<< (ostream& stream, const ThingId& right)
{
return stream << right.id_;
}

int main ()
{
ThingId thingId (11);

ostringstream extracted_identity;
extracted_identity << "Thing Id: " << thingId;

printf ("%s\n", extracted_identity.str().c_str());
fgetc (stdin);

return 0;
}


showed that it worked perfectly. It prints 11. Now all I have to do is
work out which of the other 500Kloc might be preventing the real code
from working...
 
N

Nick Keighley

Victor said:
Nick Keighley wrote:


This is covered in the FAQ 5.8.

deepest apologies. I was more checking to make sure what I was trying
to
do was even plausible. Checking a reference book showed it was. Writing

the 10 line program I should have written in the first place:-

#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>

using namespace std;

class ThingId
{
public:
ThingId (int ident = 0): id_(ident) {}
friend ostream & operator<< (ostream &stream,const ThingId &right);

private:
int id_;
};

ostream& operator<< (ostream& stream, const ThingId& right)
{
return stream << right.id_;
}

int main ()
{
ThingId thingId (11);

ostringstream extracted_identity;
extracted_identity << "Thing Id: " << thingId;

printf ("%s\n", extracted_identity.str().c_str());
fgetc (stdin);

return 0;
}


showed that it worked perfectly. It prints 11. Now all I have to do is
work out which of the other 500Kloc might be preventing the real code
from working...
 
N

Nick Keighley

Larry said:
Nick Keighley wrote:

<snip>
more representative code has been posted else-thread

Either of these should work IF 'Thing' really does have an
operator<<().

well... the real Thing really does specify in its declaration that it
has
a friend operator<<. Oddly tho' my class browser can't find a
definition... I (foolishly) assumed the browser might be broken. It's
very possible there is no definition. I've now added a definition, but
its triggered a rather large rebuild (inline is *not* your friend), so
it will
be a while before I know.
id << std::string("Thing: ") << thing;
-or-
id << "Thing: " << thing;

yes, I don't know why I struck string() in there. Moment of madness...
Then id.str() can be used to get access to the resulting string.

Perhaps 'Thing' does not have an operator<<()

I thing that may be the case
-or- perhaps it is in a namespace and needs to have the name fully
qualified

namespaces not heavily used in this code base. No sign of a namespace
in the header file for Thing.
-or- perhaps you're not including the header which defines the
operator<<() for 'Thing'

possible. I'll have another hunt for the definition

-or- perhaps you are not linking with
the module/library that contains the compiled code for 'Thing',

I think I'd get other symptoms. Complaints about the declaration of
thing for instance.
-or- perhaps ....

Do you get the idea? As Victor pointed out, there's not enough
information to provide an answer.

I get the idea! Thanks for bothering to reply to my badly structured
request.

It just finished. Still with the error. And I *can* find the
definition.
Now why can't the compiler find it...
 
L

Larry I Smith

Nick said:
deepest apologies. I was more checking to make sure what I was trying
to
do was even plausible. Checking a reference book showed it was. Writing

the 10 line program I should have written in the first place:-

#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>

using namespace std;

class ThingId
{
public:
ThingId (int ident = 0): id_(ident) {}
friend ostream & operator<< (ostream &stream,const ThingId &right);

private:
int id_;
};

ostream& operator<< (ostream& stream, const ThingId& right)
{
return stream << right.id_;
}

int main ()
{
ThingId thingId (11);

ostringstream extracted_identity;
extracted_identity << "Thing Id: " << thingId;

printf ("%s\n", extracted_identity.str().c_str());
fgetc (stdin);

return 0;
}


showed that it worked perfectly. It prints 11. Now all I have to do is
work out which of the other 500Kloc might be preventing the real code
from working...

You've included 'iostream', so why not use 'cout' & 'cin' rather than
printf() & fgetc()? e.g.

cout << extracted_identity.str() << endl;
cin.get();

Mixing 'C' IO and C++ IO can lead to problems.

Larry
 
N

Nick Keighley

<snip>

in summary it can't find the operator<<() function. This looks like a
build problem not a C++ problem (no doubt those who have been following
this
thread are unsurprised). Corrupting the Thing.cpp file did not trigger
a recompile nor did the corruption generate a syntax error. So
Thing.cpp just isn't in the build. :-(

Thanks for the help guys. Now I need to hit my build process with a big

stick.
 
N

Nick Keighley

Larry said:
You've included 'iostream', so why not use 'cout' & 'cin' rather than
printf() & fgetc()? e.g.

cout << extracted_identity.str() << endl;
cin.get();

Mixing 'C' IO and C++ IO can lead to problems.

it was a quick hack (bad habbit I know). I'm less familar with C++ i/o.
I just wanted a quick test.
 

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top