C ++ - 可变参数模板部分特化

时间:2016-02-09 08:58:36

标签: c++11 variadic-templates specialization

我们有一个简单的代码段:

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;时,我明显得到编译时错误ambiguous class template instantiation for struct A<int, double, double>

问题是:我可以做一些技巧(可能使用SFINAE)来考虑第二个模板参数,因为它具有更高的优先级并且将使用返回B的特化吗? (在第三个位置忽略类型double

注意:类型doubleint用于使示例更简单,我将使用类型特征。因此,我想避免将专业化作为解决方案:

template<class T, class... Args>
struct A<T, double, double, Args...> {
    void operator()() { std::cout << "D"; }
};

1 个答案:

答案 0 :(得分:2)

如您所知,如果第二个模板参数为C,您可以使用SFINAE不考虑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...>;