Edge-caseに関連する質問があります: 特殊化でテンプレート パラメーターの順序を (のみ) 逆にする場合、特殊化されていないバージョンに到達できますか? .
これは、おそらく不十分に記述されていると考えられるコードに関する理論的な質問です。ただし、テンプレートの構文を徹底的に理解したい。
次のように、 2 つのテンプレートの特殊化が、行内のテンプレート パラメーターの順序のみ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>'
.
特に、エラーはnot 'A<int,T2,T3>' : class template has already been defined
です。これは、2 番目の特殊化が最初の特殊化と同じ文字単位である場合に生成されるエラーです (つまり、テンプレート パラメーターの順序が反転されておらずtemplate<typename T2, typename T3>
、特殊化 #1 と同様に が読み取られます)。
template<...>
ただし、テンプレートの特殊化内の行にリストされているパラメーターの順序は、違いはないと思います。template<...>
具体的には、特殊化の行の目的は、特殊化された型名 ( ) に現れるトークンを、タイプミスではなく、構文的に有効なテンプレート パラメーターとして識別することだけだと思います。A<int, T2, T3>
この推論によればtemplate<...>
、テンプレートの特殊化の行のパラメーターの順序は違いを生じさせません。これらのパラメーターの順序のみが文字ごとに異なる 2 つのテンプレートの特殊化は、あいまいな特殊化ではなく、重複した定義と見なす必要があります。
私が正しければ、Visual Studio 2010 コンパイラは、この場合にエラーを報告するという点で正しいですが、エラーを複数定義された特殊化ではなく、あいまいな特殊化として識別するという点で正しくありません。
私は正しいですか?template<...>
テンプレートの特殊化の行のテンプレート パラメータの順序に違いはありませんか。つまり、文字ごとに同一である 2 つのテンプレートの特殊化は、2 つの異なるがあいまいではなく、同じテンプレートの特殊化の冗長な定義と見なされます。テンプレートの専門化?
私が間違っているとすれば、上記のコードの 2 つの特殊化が異なる(つまり、多重定義されていない) ということです。もしそうなら、誰かがそれらが異なる理由と、この違いがクライアントコードによってどのように示されるかを説明できますか?