Search code examples
c++templatesc++11static-assert

Assert when instancing specific template specialization


One could write a template dessigned to be specialized explicitly by the user, adding some useful error message on the default template:

template<typename T>
struct foo
{
    static_assert( sizeof(T) != sizeof(T) , "Please specialize foo for your type" );
};

Since the always-false condition depends on a template parameter the evaluation of that assert will be done during template instantation only, exactly what we want.

Now consider the inverse case: We allow the user to use a generic version of the template, but disallow him to use an specific instantation. For example:

template<typename T>
struct bar
{
    /* something useful for the user */
};

template<>
struct bar<char>
{
    static_assert( false , "No, you can't instantiate bar with char" );
};

Of course that doesn't work because the assertion doesn't depend on a template parameter, the compilation will fail even if the user doesn't instantiate bar<char>.

My question is: Is there any way to put off the evaluation of that kind of assert expression until template instantation?

EDIT: A more complex example:

template<typename T>
struct quux
{
    /* something useful for the user */
};

/* This specialization is defined to reject any instance of quux which uses a 
 * template with bool as parameter 
 */
template<template<typename> class T>
struct quux<T<bool>>
{
    static_assert( false , 
                   "Please don't use quux with a template with a bool parameter" );
};

Solution

  • No need for separate specialization:

    template<typename T>
    struct bar
    {
        static_assert( !std::is_same<T, char>::value,
            "No, you can't instantiate bar with char" );
    };
    

    EDIT: In response to your edit, again a similar thing:

    template<template<typename> class T, typename U>
    struct quux<T<U>>
    {
        static_assert( !std::is_same<U, bool>::value , 
                       "Please don't use quux with a template with a bool parameter" );
    };