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" );
};
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" );
};