Need help with my delimited stream wrapper class

R

rep_movsd

I have a utility class that lets you do something like this :

TDelimStream<char> ds(cerr, ", ");
ds << 1 << 2 << 3 << 4;

prints :
1, 2, 3, 4

Now I wish I could have it put an std::endl automatically, I have a
hunch there's no way to do this.... There seem to be no suitable
operators that have less precedence than <<

Any ideas?

Here is the implementation :

template<typename ELEM = char>
struct TDelimStream
{
typedef std::basic_ostream<ELEM, std::char_traits<ELEM> > ostream;
ostream &m_stream;
string m_sDelim;
TUntil<1> m_once;

TDelimStream(ostream &stream, const string& sDelim) :
m_stream(stream), m_sDelim(sDelim)
{
}
//////////////////////////////////////////////////////////////////////////
};

template<typename T, typename T2>
TDelimStream<T> &operator<<(TDelimStream<T> &p, const T2& val)
{
if(p.m_once.occurred())
{
p.m_stream << p.m_sDelim;
}
p.m_stream << val;
return p;
}
//////////////////////////////////////////////////////////////////////////
 
V

Victor Bazarov

I have a utility class that lets you do something like this :

TDelimStream<char> ds(cerr, ", ");
ds<< 1<< 2<< 3<< 4;

prints :
1, 2, 3, 4

Now I wish I could have it put an std::endl automatically, I have a
hunch there's no way to do this.... There seem to be no suitable
operators that have less precedence than<<

Any ideas?

How about instead of TDelimStream& your operator<< creates a temporary
object of some proxy class that also has operator<< which simply
forwards it to the same stream, and returns itself? Then the destructor
of that proxy object could forward the endl to the stream just before
going out of existence...
Here is the implementation :

template<typename ELEM = char>
struct TDelimStream
{
typedef std::basic_ostream<ELEM, std::char_traits<ELEM> > ostream;
ostream&m_stream;
string m_sDelim;
TUntil<1> m_once;

TDelimStream(ostream&stream, const string& sDelim) :
m_stream(stream), m_sDelim(sDelim)
{
}
//////////////////////////////////////////////////////////////////////////
};

template<typename T, typename T2>
TDelimStream<T> &operator<<(TDelimStream<T> &p, const T2& val)
{
if(p.m_once.occurred())
{
p.m_stream<< p.m_sDelim;
}
p.m_stream<< val;
return p;
}
//////////////////////////////////////////////////////////////////////////

V
 
R

rep_movsd

How about instead of TDelimStream& your operator<< creates a temporary
object of some proxy class that also has operator<< which simply
forwards it to the same stream, and returns itself?  Then the destructor
of that proxy object could forward the endl to the stream just before
going out of existence...

Thanks Victor, your suggestion made me remember temporaries with short
lives!

The solution was simple - I just added :

~TDelimStream()
{
cerr << endl;
}

and

inline TDelimStream<char> print()
{
return TDelimStream<char>(cerr, ", ");
}

and call it like this :


print() << 1 << 2 << 3 << 4;

And it works fine!

Just when you thing something is impossible in C++ there's always a
way!!!


Thanks
Vivek
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top