Let's have a simple snippet:
template<class T, class... Args>
struct A {
void operator()() { std::cout << "A"; }
};
template<class T, class... Args>
struct A<T, double, Args...> {
void operator()() { std::cout << "B"; }
};
template<class T, class B, class... Args>
struct A<T, B, double, Args...> {
void operator()() { std::cout << "C"; }
};
Which i can use in this way:
int main() {
A<int, int, int> a;
A<int, double, int> b;
A<int, int, double> c;
a(); b(); c();
return 0;
}
It properly returns "ABC"
. But when i declare A<int, double, double> d;
i get obviously compile time error ambiguous class template instantiation for struct A<int, double, double>
.
The question is: can i do some trick (probably using SFINAE) to take into account the second template argument as it would have a higher priority and specialization returning B would be used? (Ignoring type double
on third position)
NOTE: types double
and int
are used to make example simpler, i will use type traits. And therefore i would like to avoid following specialization as a solution:
template<class T, class... Args>
struct A<T, double, double, Args...> {
void operator()() { std::cout << "D"; }
};
As you suggest, you can use SFINAE to not consider the C
specialization if the second template argument is double
:
template<typename, class T, class... Args>
struct A_impl {
void operator()() { std::cout << "A"; }
};
template<class T, class... Args>
struct A_impl<void, T, double, Args...> {
void operator()() { std::cout << "B"; }
};
template<class T, class B, class... Args>
struct A_impl<typename std::enable_if<!std::is_same<B,double>::value>::type,
T, B, double, Args...> {
void operator()() { std::cout << "C"; }
};
template<class T,class... Args>
using A = A_impl<void,T,Args...>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With