为什么我可以使用不相交的模板参数选项来重载函数,而不是 class?
Why can I overload a function with disjoint template parameter options, but not a class?
这样编译:
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; } };
^
第二种重载对我来说似乎非常合理,不会有歧义,因为类型和值是不相交的。那为什么不允许呢?
这就是 class 模板的工作方式。您从一个主要模板开始:
template <class T, class U> struct A;
然后你可以专攻它。所有专业必须与主要专业相匹配:
template <class T> struct A<T, T> {...}; // OK
template <class T> struct A<T> {...}; // nope
目前的定义很简单:首先查找主要的,然后根据部分排序规则选择专业化。
为了满足您的需求,选择正确的 class 模板的语言将发生相当大的变化。特别是考虑到您可以简单地实现您想要的:
template <class T, T V>
struct A<T, std::integral_constant<T, V>> {...};
这样编译:
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; } };
^
第二种重载对我来说似乎非常合理,不会有歧义,因为类型和值是不相交的。那为什么不允许呢?
这就是 class 模板的工作方式。您从一个主要模板开始:
template <class T, class U> struct A;
然后你可以专攻它。所有专业必须与主要专业相匹配:
template <class T> struct A<T, T> {...}; // OK
template <class T> struct A<T> {...}; // nope
目前的定义很简单:首先查找主要的,然后根据部分排序规则选择专业化。
为了满足您的需求,选择正确的 class 模板的语言将发生相当大的变化。特别是考虑到您可以简单地实现您想要的:
template <class T, T V>
struct A<T, std::integral_constant<T, V>> {...};