ための8.3.6([dcl.fct.default])/ 4、
特定の関数宣言では、デフォルト引数を持つパラメーターに続く各パラメーターは、この宣言または前の宣言で指定されたデフォルト引数を持つか、関数パラメーターパックである必要があります。
以下をコンパイルする必要があります。
#include <iostream>
template<typename ...Ts>
void foo(int i=8, Ts... args)
{
std::cout << "Default parameters \t= " << i << "\n";
std::cout << "Additional params \t= " << sizeof...(Ts) << "\n";
}
int main()
{
foo(); // calls foo<>(int)
foo(1, "str1", "str2"); // calls foo<const char*, const char*>(int, const char*, const char*)
foo("str3"); // ERROR: does not call foo<const char*>(int, const char*)
return 0;
}
ただしfoo("str3")
、コンパイラが混乱するため、コンパイルされません。呼び出しに一致する関数foo(const char*)
がなく、"str3"
(type const char*
)をtypeに変換できないと文句を言いint
ます。
関数のオーバーロードに頼るか、名前付きパラメーターのイディオムを使用することで、この問題を回避できることを理解しています(c ++の可変長関数のデフォルト値パラメーターの配置場所とデフォルトの引数と可変個引数関数を参照)。ただし、コンパイラが愚かであるのか、それとも上記のコード例で意図した動作が実装されていない本当の理由があるのかを知りたいと思います。つまり、関数を明示的にインスタンス化しても、コンパイラが文句を言うのはなぜfoo<const char*>(int, const char*)
ですか?これは、明示的なインスタンス化がデフォルトパラメータの値を単に無視するかのようです。どうして?
あなたが引用している基準は、形成することが合法であると言っているだけです
template<typename ...Ts>
void foo(int i=8, Ts... args)
ただし、これを呼び出すときはint
、最初のパラメーターとしてを渡す必要があります。そうしないと、過負荷の解決中に関数が考慮されません。あなたがするとき
foo("str3");
コンパイラーはfoo
、const char*
またはをとる関数を探しconst char(&)[5]
ます。これが唯一のパラメーターだからです。つまり、関数はint
最初のパラメーターを予期しているか、パラメーターがまったくないため、完全に無視されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加