Force template method in non-template class

2019-02-28 03:52发布

问题:

I try to achieve the following behavior/syntax/usage of this class:

Data1 dataType1;
Data2 dataType2;

int intType;
float floatType;

dataType1.method( intType );
dataType1.method( floatType );

dataType2.method( intType );
dataType2.method( floatType );

My approach would be this:

struct CDataBase
{
    template< typename T > virtual void method( T type ) = 0;
};

struct CData1 : CDataBase
{
    template< typename T > void method( T type ) {}
};

struct CData2 : CDataBase
{
    template< typename T > void method( T type ) {}
};

However virtual template methods aren't possible. Also there is no need for an actual base class, However I have to ensure that some classes got a (template) 'method()' implemented.

How do I force a non-templated class/struct to override a template method?


EDIT: This is my actual layout:

struct Data0
{
    int someVar;

    template< class T >
    void decode( T& type )
    {
        type.set( someVar );
    }
};

EDIT: in the current version of C++ (11) the behavoir I try to achieve isn't possible. In addition to that, I should really recode this part to avoid this problem. However I accept the only answer given, thanks for you affort.

回答1:

The basic idea to check for specific functions implemented of a given template parameter type, is to try instantiate function pointers of these. The compiler will complain, if the function pointer initializations cannot be resolved.

Here's some sample code to illustrate the principle:

template<typename T>
void check_has_foo_function() {
    void (T::*check)(int, double) = &T::foo;
    (void)check;
}

struct A {
    void foo(int, double) {};
};

struct B {
    void bar(int, double) {};
};

template<typename CheckedClass>
struct Client {
    void doSomething() {
        check_has_foo_function<CheckedClass>();
        CheckedClass x;
        x.foo(5,3.1415);
    }
};

int main() {

    Client<A> clientA;
    clientA.doSomething();

    // Uncomment the following lines to see the compilation fails
    // Client<B> clientB;
    // clientB.doSomething();
    return 0;
}

Note the call to the check_has_foo_function<CheckedClass>(); function will be completely optimized out, and doesn't have any impact on runtime performance.

Based upon this, further abstractions could be provided (e.g. to generate checks using preprocessor macros). I have published a little experimental framework on GitHub that uses these techniques.