我们有一个简单的片段:
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"; }
};
我可以这样使用:
int main() {
A<int, int, int> a;
A<int, double, int> b;
A<int, int, double> c;
a(); b(); c();
return 0;
}
它正确返回“ABC”.但是当我声明A< int,double,double> d;我明显得到结构A< int,double,double>的编译时错误模糊类模板实例化.
问题是:我可以做一些技巧(可能使用SFINAE)来考虑第二个模板参数,因为它具有更高的优先级,并且将使用返回B的特化吗? (忽略第三个位置的双重类型)
注意:类型double和int用于使示例更简单,我将使用类型特征.因此,我想避免专业化作为解决方案:
template<class T, class... Args>
struct A<T, double, double, Args...> {
void operator()() { std::cout << "D"; }
};
最佳答案 如您所知,如果第二个模板参数为double,则可以使用SFINAE不考虑C专精:
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...>;