¿Cómo puedo verificar si un tipo es una instanciación de una plantilla de clase determinada?

¿Es posible verificar que un tipo sea una instanciación de una plantilla en particular?

Tengo una plantilla de clase donde uno de los parámetros de la plantilla debe ser una instanciación de una plantilla particular o algún otro tipo. Por ejemplo, considere esta simple definición de una lista de tipos:

struct null_type; template  struct typelist { // Tail must be a typelist or null_type typedef Head head; typedef Tail tail; }; 

Ahora, me gustaría asegurarme de que el tipo proporcionado para el parámetro de plantilla Tail sea ​​siempre una instanciación de typelist o null_type . Podría usar especialización parcial para definir la plantilla solo para esos casos, como esta:

 template  struct typelist; // default, not defined template  struct typelist< Head, typelist > // Tail = typelist, ok { typedef Head head; typedef typelist tail; }; template  struct typelist // Tail = null_type, ok { typedef Head head; typedef null_type tail; }; 

Sin embargo, termino duplicando código, que es algo que me gustaría evitar. Idealmente, necesitaría un rasgo para probar si un tipo es una instanciación de una plantilla, para usarla con enable_if o en aserciones estáticas:

 #include  #include  struct null_type; template  struct typelist { static_assert( boost::mpl::or_< is_instantiation_of, std::is_same >::value, "Tail must be a typelist or null_type" ); typedef Head head; typedef Tail tail; }; 

¿Ya está disponible ese rasgo ( is_instantiation_of ) en la biblioteca estándar o en Boost? ¿Es posible escribir uno?

Se me ocurrió la siguiente solución, usando plantillas variadicas de C ++ 11 y especialización parcial simple:

 #include  template < template  class Template, typename T > struct is_instantiation_of : std::false_type {}; template < template  class Template, typename... Args > struct is_instantiation_of< Template, Template > : std::true_type {}; 

Se podría adaptar a C ++ 03 utilizando el preprocesador para generar versiones para un número variable de parámetros de plantilla, pero quizás haya una manera más simple.