为什么我可以使用不相交的模板参数选项重载函数,而不是类?

时间:2016-03-27 19:23:09

标签: c++ templates c++11 overloading

编译:

template <typename T, typename T2> void foo() { std::cout << "in foo() for two types." << std::endl; }
template <typename T, T Value>     void foo() { std::cout << "in foo() for a type and a value." << std::endl; }

这不是(GCC 4.9.3 with -std=c++11):

template <typename T, typename T2> class A { A() { std::cout << "in A::A() for two types." << std::endl; } };
template <typename T, T Value>     class A { A() { std::cout << "in A::a() for a type and a value." << std::endl; } };

错误是:

a.cpp:6:23: error: template parameter ‘class T2’
 template <typename T, typename T2> class A { A() { std::cout << "in A::A() for two types." << std::endl; } };
                       ^
a.cpp:7:42: error: redeclared here as ‘T Value’
 template <typename T, T Value>     class A { A() { std::cout << "in A::a() for a type and a value." << std::endl; } };
                                          ^

第二种过载似乎对我来说是完全合理的,不存在歧义,因为类型和值是不相交的。那为什么不允许呢?

1 个答案:

答案 0 :(得分:3)

这就是类模板的工作原理。您从主模板开始:

template <class T, class U> struct A;

然后你可以把它专门化。所有专业化必须与主要专业匹配:

template <class T> struct A<T, T> {...}; // OK
template <class T> struct A<T> {...}; // nope

这就是它当前的定义方式:首先查找主要内容,然后根据部分排序规则选择专业化。

为了满足您的需求,选择正确的类模板的语言会发生很大变化。特别是考虑到你可以简单地实现你想要的东西:

template <class T, T V>
struct A<T, std::integral_constant<T, V>> {...};