我有一个与Edge-case 相关的问题:当(仅)在专业化中反转模板参数的顺序时,是否可以达到非专业化版本?.
这是一个理论问题,涉及可能被认为写得不好的代码。但是,我想彻底了解模板语法。
假设两个模板特化仅在行内模板参数的顺序上有所不同template<...>
,如下所示:
#include <iostream>
// Primary template
template<typename T1, typename T2, typename T3>
class A
{};
// Specialization #1
template<typename T2, typename T3>
class A<int, T2, T3>
{};
// Specialization #2
// Differs only in order of parameters in the "template<...>" line
template<typename T3, typename T2>
class A<int, T2, T3>
{};
int main()
{
A<int, int, int> a; // <-- Compiler error: Ambiguous template specializations
return 0;
}
在 Visual Studio 2010 编译器中,错误涉及不明确的模板专业化:'A<T1,T2,T3>' : more than one partial specialization matches the template argument list. could be 'A<int,T2,T3>' or 'A<int,T2,T3>'
.
特别是,错误 is not 'A<int,T2,T3>' : class template has already been defined
,这是当第二个特化与第一个特化是逐字符相同时产生的错误(即,模板参数的顺序不颠倒,并且读取template<typename T2, typename T3>
,就像在特化 #1 中一样)。
但是,我认为template<...>
模板专业化中的行中列出的参数顺序没有区别。具体来说,我认为特化中的template<...>
行的目的只是将出现在特化类型名称 ( ) 中的标记识别A<int, T2, T3>
为语法上有效的模板参数,而不是拼写错误。根据这个推理,template<...>
模板特化的行中参数的顺序应该没有区别,并且两个仅在这些参数的顺序上逐字符不同的模板特化应该被视为重复定义,而不是模棱两可的特化。
如果我是正确的,那么 Visual Studio 2010 编译器是正确的,因为它在这种情况下会报告错误,但不正确的是它会将错误标识为模棱两可的专业化,而不是多重定义的专业化。
我对么?template<...>
模板特化行中模板参数的顺序是否没有区别,因此两个相同的模板特化应该被视为相同模板特化的冗余定义,而不是两个不同但模棱两可的,模板专业化?
如果我不正确,那么上面代码中的两个专业化确实是不同的(即,不是多重定义的)。如果是这样,有人可以解释为什么它们不同以及客户端代码如何证明这种差异?