Search code examples
c++templatesspecializationpartial-specialization

C++ template specialization via a base class


I want to be able to make the compiler shout when i call a constructor of foo with a class that is NOT derived from _base*. The current code allows only for foo<_base*> itself. Any easy solution ?

class _base
{
public:
    // ...
};

class _derived: public _base
{
public:
    // ...
};

template <typename T>
class foo
{
public:
    foo ()      { void TEMPLATE_ERROR; }
};

template <> foo<_base*>::foo () 
{
    // this is the only constructor
}

main-code:

foo<_base*>    a;    // should work 
foo<_derived*> b;    // should work (but doesnt)
foo<int*>      c;    // should not work (and infact doesnt)

Solution

  • Without Boost you can use something like the following to determine whether a pointer-to-type can be implicitly cast to another pointer-to-type:

    template <class Derived, class Base>
    struct IsConvertible
    {
        template <class T>
        static char test(T*);
    
        template <class T>
        static double test(...);
    
        static const bool value = sizeof(test<Base>(static_cast<Derived*>(0))) == 1;
    };
    

    To make it trigger an error at compile-time, you can now use value in an expression that causes an error if it is false, for example typedef a negative-sized array.

    template <typename T>
    class foo
    {
    public:
        foo ()
        {
            typedef T assert_at_compile_time[IsConvertible<T, _base>::value ? 1 : -1];
        }
    };