<< friend

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

Given

class Fred {
public:
friend std::eek:stream& operator<< (std::eek:stream& o, const Fred& fred);
...
private:
int i_; // Just for illustration
};

std::eek:stream& operator<< (std::eek:stream& o, const Fred& fred)
{
return o << fred.i_;
}

from the FAQ, what is wrong with the following class declaration?
(How TLSFile is implemented isn't really germane here)

class
TLSFileStream : public TLSFile
{
private:
std::string buf;

public:
friend std::eek:stringstream &operator<< (std::eek:stringstream &ss, TLSFileStream &lsf)
{return(ss << lsf.AsString());} // I get a warning about
// references initialized with
// ostream - huh??
WriteStr( std::str s );
};

template <class T>
TLSFileStream& operator<< (TLSFileStream& lsf, const T& t)
{
std::eek:stringstream ss;
ss << t; // trying to use << operator above, says that << isn't
// implemented for TLSFile - huh?? ;(
lsf.WriteStr( ss.str() );
return lsf;
};
 
J

John Carson

Christopher Benson-Manica said:
Given

class Fred {
public:
friend std::eek:stream& operator<< (std::eek:stream& o, const Fred&
fred); ...
private:
int i_; // Just for illustration
};

std::eek:stream& operator<< (std::eek:stream& o, const Fred& fred)
{
return o << fred.i_;
}

from the FAQ, what is wrong with the following class declaration?
(How TLSFile is implemented isn't really germane here)

class
TLSFileStream : public TLSFile
{
private:
std::string buf;

public:
friend std::eek:stringstream &operator<< (std::eek:stringstream &ss,
TLSFileStream &lsf) {return(ss << lsf.AsString());} // I get a
warning about // references
initialized with // ostream -
huh?? WriteStr( std::str s );
};


Try

friend std::eek:stringstream &operator<< (std::eek:stringstream &ss,
TLSFileStream &lsf)
{
ss << lsf.AsString();
return ss;
}

I presume this is a typo (cut and paste is always better than typing), but

WriteStr( std::str s );

is missing a return type and there is no such thing as std::str.

template <class T>
TLSFileStream& operator<< (TLSFileStream& lsf, const T& t)
{
std::eek:stringstream ss;
ss << t; // trying to use << operator above, says that << isn't
// implemented for TLSFile - huh?? ;(
lsf.WriteStr( ss.str() );
return lsf;
};

Junk the concluding semi-colon.
 
C

Christopher Benson-Manica

friend std::eek:stringstream &operator<< (std::eek:stringstream &ss,
TLSFileStream &lsf)
{
ss << lsf.AsString();
return ss;
}

This worked, but can you explain why this is correct while my version
was wrong?
 
J

John Harrison

Christopher Benson-Manica said:
This worked, but can you explain why this is correct while my version
was wrong?

Because the result of ss << lsfAsString() is a temporary (like the result of
all function calls).

You cannot bind non-const references to a temporary.

john
 
J

John Harrison

John Harrison said:
Because the result of ss << lsfAsString() is a temporary (like the result of
all function calls).

You cannot bind non-const references to a temporary.

Actually that might not be right, a definitive answer would need to know the
return type of lsfAsString(), and what overloads were declared on operator
<< for ostringstream and the return type of lsfAsString() and what the
return type of that overload was.

But I'm guessing that operator << as used in 'ss << lsf.AsString()' returns
a std::eek:stream&, which cannot be converted to a std::eek:stringstream&.

Which brings up the real problem with your code, why

friend std::eek:stringstream &operator<< (std::eek:stringstream &ss, TLSFileStream
&lsf)?

Why not

friend std::eek:stream &operator<< (std::eek:stream &ss, TLSFileStream &lsf)?

There are no sensible reasons for the former.

john
 
C

Christopher Benson-Manica

John Harrison said:
Which brings up the real problem with your code, why
friend std::eek:stringstream &operator<< (std::eek:stringstream &ss, TLSFileStream
&lsf)?
friend std::eek:stream &operator<< (std::eek:stream &ss, TLSFileStream &lsf)?

Ooh, good call, although...
There are no sensible reasons for the former.

Does the fact that there is pretty much no way a this class will be
used with any ostream other than an ostringstream count for anything?
I know you're going to say "Well, what about future users?" - let's
just say that when someone wants to use this object with a regular
ostream, the need for the object itself will likely be gone :)
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top