应该在“模板< ...>”中更改模板参数的顺序专门化的结果会导致重复的定义或歧义吗?

时间:2012-06-17 16:11:28

标签: c++ templates

我有一个与Edge-case: When (only) reversing order of template parameters in specialization, can non-specialized version ever be reached?相关的问题。

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

假设两个模板特化按照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<...>行中的模板参数的顺序是否与不同,这样两个模板特化相同,否则将被视为字符的冗余定义相同的模板专业化,而不是两个不同但模糊的模板专业化?

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

1 个答案:

答案 0 :(得分:1)

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

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

如果重新排序他们的位置,参数列表会变得不同,因为不同的类型作为参数传递。所以你没有重新定义部分专业化。