Interfaces and generic templates

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

(To the extent that this is a rehash of earlier questions, sorry.)

I feel like I'm starting to get the hang of how to make classes work
with << and >>, so now I have the (possibly dumb) idea to create
generic interfaces that use these, making it easy to subclass our
existing classes and make them behave a little better in the C++
world. I'm going to describe what I'm doing in some detail - feel
free to interject criticism at any point, since I'm not at all sure
what can be done better...

To start with: Create a class/interface Receivable that serves to
buffer data written to it (currently, a lot of code we have takes only
const char *'s for writing):

class Receivable // Buffered line input via <<
{
protected:
std::eek:stringstream outbuf;

public:
virtual void ProcessInput( std::string& s )=0;

template <class T> void Buffer( const T& t );
template <class T> Receivable& operator<< ( const T& t );
void Flush() {ProcessInput(outbuf.str()+"\n");}
};

template <class T> void Receivable::Buffer( const T& t )
{
outbuf << t;
std::string& buf=outbuf.str();
if( buf[buf.length()-1]=='\n' ) {
ProcessInput( buf );
}
outbuf.clear();
outbuf.str( "" );
}

template <class T> Receivable& Receivable::eek:perator<< ( const T& t )
{
Buffer( t );
return( *this );
}

Okay, great, maybe. Now create an interface Stringizable that allows
classes that implement it to appear on the right side of << operators:

class Stringizable
{
virtual const char* ToString()=0; // returns const char * because
// that's what a lot of code
// already returns
};

Uh-huh, you say. But how to make Stringizables work with the <<
operator? Maybe

template <class T>
T& __fastcall operator<< ( const T& t, const Stringizable& s )
{
t << s.ToString();
return( t );
}

Fine and dandy, as long as T doesn't implement Stringizable, eh? How
can I make it that general? But onward - now I should be able to put
these interfaces to work in my previously-mentioned TLSFileStream
class:

class
TLSFileStream : public TLSFile, public Receivable, public Stringizable
{
typedef TLSFile Inherited;

public:
CPCHAR __fastcall ToString() {return(AsString());} // TLSFile
void __fastcall ProcessInput( std::string& s )
{
Inherited::Write( s.c_str() ); // implemented by TLSFile
}
~TLSFileStream() {Flush();}
};

So theoretically, I should be able to do

TLSFileStream fs1, fs2;
....
fs1 << fs2;

But, as I noted above, TLSFileStream implements both interfaces, and
thus the compiler can't figure it out.

Help/suggestions, please :)
 
C

Christopher Benson-Manica

Christopher Benson-Manica said:
template <class T> void Receivable::Buffer( const T& t )
{
outbuf << t;
std::string& buf=outbuf.str();
if( buf[buf.length()-1]=='\n' ) {
ProcessInput( buf );
}
outbuf.clear();
outbuf.str( "" );
}

Whoops - just found the bug here. Obviously (directed at myself...)
this should be

template <class T> void Receivable::Buffer( const T& t )
{
outbuf << t;
std::string& buf=outbuf.str();
if( buf[buf.length()-1]=='\n' ) {
ProcessInput( buf );
outbuf.clear(); // fixed
outbuf.str( "" ); // fixed
}
}
 

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

Similar Threads

templates 10
A mess with inheritance, virtual classes , and templates. 2
On templates and not declared 2
templates?? 2
Templates 4 a Nu-B 1
templates 2
Generic ostream operator<<? 32
Templates and g++ 4

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top