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.)
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.