编译:
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; } };
^
第二种过载似乎对我来说是完全合理的,不存在歧义,因为类型和值是不相交的。那为什么不允许呢?
答案 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>> {...};