更改专用化"template<...>"行中模板参数的顺序是否会导致定义重复或歧义?



我有一个与边缘情况有关的问题:当(仅)在专用化中反转模板参数的顺序时,是否可以达到非专用版本?

这是一个涉及代码的理论问题,可能会被认为写得不好。 但是,我想彻底了解模板语法。

假设两个模板专用化仅在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>'

特别是,错误不是'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<...>行中的模板参数顺序是否没有区别,因此两个相同的模板专用化应被视为同一模板专用化的冗余定义,而不是两个不同但模棱两可的模板专用化?

如果我不正确,那么上面代码中的两个专业确实是不同的(即,不是乘法定义的)。 如果是这样,有人可以解释为什么它们不同以及客户端代码如何证明这种差异吗?

部分专用化的标识是传递给其模板的参数列表。模板类型参数名称表示特定的依赖类型,其标识包括它们在其模板参数列表中的位置及其模板参数列表的嵌套深度(即,如果成员模板是类模板的成员,则成员模板的列表比其封闭模板嵌套的级别多一级)。

这是有道理的,因为您需要修改两个不同的函数模板,这些模板相互重载,并且仅在模板参数顺序上有所不同。它们的实例化行为是不同的,因为它们的位置直接对应于函数模板调用的模板参数列表中的相应参数。

如果对其位置重新排序,则参数列表将变得不同,因为不同类型的参数作为参数传递。因此,您不是在重新定义部分专业化。

最新更新