私はいくつかの興味深いバリデーショナルなテンプレート関数の動作に出くわしました。誰もがこれを定義する標準の関連ルールを指摘できますか?非末尾のパラメータパックの動作に戸惑う
GCC,ICCおよびMSVCは、次のコードを正常にコンパイルします(Clangはそうではありませんが、これはコンパイラのバグによるものです)。 foo
にこの呼び出しで
template<class A, class... Bs, class C>
void foo(A, Bs..., C) { }
int main()
{
foo<int, int, int, int>(1, 2, 3, 4, 5);
}
テンプレート引数がA
とBs
のために提供され、その後、C
はint
なると推定されます。
しかし、我々は単に最後の二つのテンプレートパラメータを反転場合:
template<class A, class C, class... Bs>
void foo(A, Bs..., C) { }
その後allthreecompilersスローエラーを。ここではGCCからのいずれかになります。
main.cpp: In function 'int main()':
main.cpp:8:42: error: no matching function for call to 'foo(int, int, int, int, int)'
foo<int, int, int, int>(1, 2, 3, 4, 5);
^
main.cpp:4:6: note: candidate: template<class A, class C, class ... Bs> void foo(A, Bs ..., C)
void foo(A, Bs..., C) { }
^~~
main.cpp:4:6: note: template argument deduction/substitution failed:
main.cpp:8:42: note: candidate expects 4 arguments, 5 provided
foo<int, int, int, int>(1, 2, 3, 4, 5);
^
物事をより面白くするために、最初のfoo
ためinvalidであり、第二のためvalidのみ四つの引数で呼び出します。
第二に、C
を明示的に供給されなければならないのに対しfoo
、C
の最初のバージョンで、推測しなければならないようです。
標準のどの規則でこの動作が定義されていますか?
最初の例は、コンパイルしたものではありません。それは不公平です。 –
@SamVarshavchik理由を説明できますか? – TartanLlama
テンプレートは4つのパラメータで明示的にインスタンス化されています。テンプレートは、パラメータと同じパラメータを関数呼び出しに展開します。関数呼び出しには4つのパラメータが必要です。 4つのパラメータを必要とする関数呼び出しに5つの実際のパラメータを渡すと、不正な形式になります。 –