suppose I have these declarations
template class User;
template class Data;
and want to implement
As you only want to implement it when a single condition is true, the easiest solution is to use a static assertion. It does not require SFINAE, gives a clear compile error if used incorrectly and the declaration of User<>
does not need to be adapted:
template class User {
static_assert(is_Data::value, "T is not (a subclass of) Data<>");
/** Implementation. **/
};
See also: When to use static_assert instead of SFINAE?. The static_assert
is a c++11 construct, however there are plenty workarounds available for pre-c++11 compilers, like:
#define STATIC_ASSERT(consdition,name) \
typedef char[(condition)?1:-1] STATIC_ASSERT_ ## name
If the declaration of user<>
can be changed and you want two implementations depending on the value of is_Data
, then there is also a solution that does not use SFINAE:
template::value> class User;
template class User {
static_assert(is_Data::value, "T is not (a subclass of) Data<>"); // Optional
/* Data implementation */
};
template class User {
static_assert(!is_Data::value, "T is (a subclass of) Data<>"); // Optional
/* Non-data implementation */
};
The static assertions only checks whether the user did not accidentally specify the template argument D
incorrectly. If D
is not specified explicitly, then the static assertions can be omitted.