次の例を検討してください。
// Mind the default template argument
template <typename T = int>
struct Test;
template <typename T>
struct Test
{
};
template <typename T>
struct Test;
int main()
{
Test<> t;
return 0;
}
上記のコードは、MSVC 19、gcc 8、およびclang8で正常にコンパイルできます。期待どおりです。
次に、デフォルトのテンプレート引数をクラステンプレートの定義に移動しましょう。
template <typename T>
struct Test;
// Mind the default template argument
template <typename T = int>
struct Test
{
};
template <typename T>
struct Test;
int main()
{
Test<> t;
return 0;
}
これは、3つのコンパイラすべてでも機能します。
ただし、クラステンプレートの定義の後にデフォルトの引数を配置するTest
と、Visual Studioはソースのコンパイルを拒否し、次のように文句を言います。
マークされた行(!):テンプレート引数が少なすぎます
template <typename T>
struct Test;
template <typename T>
struct Test
{
};
// Mind the default template argument
template <typename T = int>
struct Test;
int main()
{
Test<> t; // (!)
return 0;
}
それはMSVCのバグですか?
cppreferenceは、この件に関して非常に明確だと思います。定義のデフォルトのテンプレート引数とすべての宣言をマージする必要があります。定義に従った宣言には特別な例外はありませんよね?
これはバグです。パー[temp.param] / 12
使用可能なデフォルトのテンプレート引数のセットは、デフォルトの関数の引数([dcl.fct.default])と同じ方法で、テンプレートの以前のすべての宣言からのデフォルトの引数をマージすることによって取得されます。
t
後に来るので
// Mind the default template argument
template <typename T = int>
struct Test;
int
パラメータが指定されていないため、デフォルトのパラメータを考慮して使用する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加