Click to See Complete Forum and Search --> : is there a way to demand interfaces in C++?


Trazlo Trevize
April 12th, 2008, 09:32 PM
Heya ya'll,

I've hit a bit of a conundrum, and I don't really expect that there *is* a nice answer in the C++ language at the moment, but I've reason enough to doubt I know much about c++ so thus I've reason enough to hope that maybe there is an answer.

Anyway, ya'll might know that Java has Interfaces. I like those since it makes it a lot easier on me to write lotsa classes that all conform to that Interface.

Unfortunately, I don't like Java that much, and I prefer C++.

Unfortunately, I *love* templates. I find templated member functions to be incredibly utile.

Templated member functions *cannot* be virtual. That's cool with me. I don't even *want* them to be virtual.

Unfortunately, as far as I know, the only way to emulate Interfaces in C++ is to have an abstract base class with pure virtual functions.
In Java, every darn member function is virtual, so this C++ approach to Interfaces gives the exact same virtual behavior.

Unfortunately, "templated member functions *cannot* be virtual," and as I said before that's cool with me, but I *did* want to have an Interface which demands the presence of some templated member functions. To do this in C++ (as far as I know) I would have to declare a pure virtual templated member function. This does not happen.

Fortunately, I don't really need any virtual behavior. I just want something which I can use to get the compiler to kick me if I haven't written a certain set of functions for a certain class (and I can assure you that some of those functions that the class had better have are going to be templated member functions).

So in conclusion, as far as I know, I'm screwed if I desire an Interface in C++ which demands that a class has a templated member function. If any of ye good folk know of any ways I can get this kind of behavior, please do tell, and I shall be eternally grateful.

Preferably, solutions within the language are what I'm looking for, but if there's some sorta nifty awesome code checker which could do the job, I'd be glad to hear it.

Plasmator
April 12th, 2008, 10:11 PM
Somewhat limited, but you might be able to put it to good use:

template<typename T> struct MyInterface
{
virtual ~MyInterface() {}
virtual void Foo(const T&) = 0;
};

template<typename T> struct MyObject : MyInterface<T>
{
void Foo(const T&)
{
//...
}
};

Trazlo Trevize
April 12th, 2008, 11:45 PM
That's crafty, sly, and nifty, but I can't see how to get the functionality out of it that I desire.

For Instance :

// based on the code previous. . .
// just some things I want to shove down the throat of the foo function
someOtherType veryUsefulData = someOtherType( );
someType moreVeryUsefulData = someType( );
// make an instance
MyObject<someType> blissfulInstance = MyObject<someType>( );
// foo'em
blissfulInstance.foo( veryUsefulData ) ;// ain't happenin'
blissfulInstance.foo( moreVeryUsefulData ) ;// happens

In the above code blissfulInstance is stuck as MyObject<someType>, so unless there's a way to easily use it as a MyObject<someOtherType> on a whim, I don't know how to wrangle the functionality out of it.

laserlight
April 13th, 2008, 01:10 AM
Fortunately, I don't really need any virtual behavior. I just want something which I can use to get the compiler to kick me if I haven't written a certain set of functions for a certain class (and I can assure you that some of those functions that the class had better have are going to be templated member functions).
The compiler will automatically do that if you actually use those functions but they are not provided. Of course, if you do not use them at the moment but want them to be provided anyway, then unfortunately the compiler will not recognise that as a problem unless you try to emulate pure interface constructs.

Trazlo Trevize
April 13th, 2008, 12:21 PM
Hmm, that's right. The compiler does whine if you use the functions & they aren't there.

It's a bit roundabout, and this code isn't something I would leave in when you compile a finished product, but for purposes of making sure you do everything right while you're still designing it, I think this does give me the behavior I wanted.


// some hapless class that I wish to conform to an interface
class MyCherishedObject
{
private :// It's not default constructable
MyCherishedObject( )
{
}
public :
MyCherishedObject( int someParameter )
{
}
public :
// a function called foo, which is declared
template<class type>
void foo( ) {}

// a function called woo, which is declared but is not declared as a
// templated member function
//template<class type>
void woo( ) {}

// a function called roo, which is not declared
//template<class type>
// void roo( ) {}
} ;


// some hapless class that I wish to conform to an interface
class MyDearObject
{
public :
// a function called foo, which is declared
template<class type>
void foo( ) {}

// a function called woo, which is declared but is not declared as a
// templated member function
//template<class type>
void woo( ) {}

// a function called roo, which is not declared
//template<class type>
// void roo( ) {}

} ;

// a specific interface which can be made to make it so nothing compiles
// unless *type* implements the functions this interface demands.
template<class type>
class anInterface
{public :
// for default constructable things
anInterface( )
{ this->demandInterface( type( ) ) ;
}
// for things which you don't want to specify their constructors in the interface
anInterface( type& instance )
{ this->demandInterface( instance ) ;
}
private :
void demandInterface( type& instance )
{ // makes the compiler kick me.
instance.foo<int>( ) ;
// makes the compiler kick me.
instance.woo<int>( ) ;
// makes the compiler kick me.
instance.roo<int>( ) ;
}
} ;

// main
void main()
{// makes the compiler kick me
anInterface<MyDearObject>( ) ;
// makes the compiler kick me
anInterface<MyCherishedObject>( MyCherishedObject( 4 ) );
}

So yeah, that does it as far as I can tell, thanks laserlight! Only issues are that it's kinda clunky.

If anyone has another way though, I'm all ears.