Reputation: 245
So in a template class, I was trying to instantiate different member according to some information provided statically. In the below template, if some condition holds, the selectiveMember
is contained within SelectiveClass
, otherwise, the template is intended to be instantiated without selectiveMember
but still contain foo
.
template<typename T>
struct SelectiveClass{
void foo(){...}
template<condition_check<T>::type=0>
void selectiveMember{...}
}
However, this kind of implementation would discard the whole class if condition is not satisfied. Nevertheless, using the CRTP technique, we can reach the purpose.
template<typename T>
struct SelectiveClass: Specialize<T>{
void foo(){...}
}
template<typename T>
struct Specialize{
template<condition_check<T>::type=0>
void selectiveMember{...}
}
But with this technique, each selective member would require another specialized inheritance.
So my question is: Is there any more elegant way to allow this kind of selective member template?
Upvotes: 1
Views: 113
Reputation: 3823
The reason why your enable_if
doesn't work the way you want it to, is because it is not used in the immediate context (see, for instance, here). However, if you insert a default template argument in the selectiveMember
function, you can achieve what you need. In the example below, I am using a concrete example of a condition
but you can replace this with your own.
#include <type_traits>
template<typename T>
struct SelectiveClass{
void foo(){}
template <class X = T, std::enable_if_t<std::is_integral<T>::value, X>* = nullptr>
void selectiveMember(){}
};
using test_int = SelectiveClass<int>;
using test_double = SelectiveClass<double>;
int main() {
test_int x;
test_double y;
x.selectiveMember();
// y.selectiveMember(); fails to compile as expected
}
Upvotes: 2