using SFINAE for template class specialisation

Walter picture Walter · Oct 12, 2012 · Viewed 17k times · Source

suppose I have these declarations

template<typename T> class User;
template<typename T> class Data;

and want to implement User<> for T = Data<some_type> and any class derived from Data<some_type> but also allow for other specialisations defined elsewhere.

If I didn't already have the declaration of the class template User<>, I could simply

template<typename T,
         typename A= typename std::enable_if<is_Data<T>::value>::type>
class User { /*...*/ };

where

template<template<typename> data>> struct is_Data
{ static const bool value = /* some magic here (not the question) */; };

However, this has two template parameters and thus clashes with the previous declaration, where User<> is declared with only one template parameter. Is there anything else I can do?

(Note

template<typename T,
         typename A= typename std::enable_if<is_Data<T>::value>::type>
class User<T> { /*...*/ };

doesn't work (default template arguments may not be used in partial specializations), nor does

template<typename T> class User<Data<T>> { /*...*/ };

as it doesn't allow types derived from Data<>, neither does

template<typename T>
class User<typename std::enable_if<is_Data<T>::value,T>::type>
{ /*...*/ };

since template parameter T is not used in partial specialization.)

Answer

Walter picture Walter · Oct 12, 2012

IF the original declaration of User<> can be adapted to

template<typename, typename=std::true_type> class User;

then we can find a solution (following Luc Danton's comment, instead of using std::enable_if)

template<typename>
struct is_Data : std::false_type {};
template<typename T>
struct is_Data<Data<T>> : std::true_type {};

template<typename T>
class User<T, typename is_Data<T>::type >
{ /* ... */ };

However, this doesn't answer the original question, since it requires to change the original definition of User. I'm still waiting for a better answer. This could be one that conclusively demonstrates that no other solution is possible.