たとえば、次のようなものです。
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
上記のコードは C++ で正確に何を意味するのでしょうか? G++ で問題なくコンパイルできます。これが役立つシナリオや、何をすべきかさえ想像できないことに注意してください。私はただ興味があります。
たとえば、次のようなものです。
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
上記のコードは C++ で正確に何を意味するのでしょうか? G++ で問題なくコンパイルできます。これが役立つシナリオや、何をすべきかさえ想像できないことに注意してください。私はただ興味があります。
void my_function(int it=42, ...)
この関数は GCC で正常にコンパイルされると言いましたが、デフォルトの引数を使用することはできません。この関数を使用するには、いわゆるデフォルト パラメータの引数も渡す必要があります。
my_function("string", 98, 78, 99); //error
my_function(898, "string", 98, 78, 99); //ok, but the param 'it' becomes 898
自問してみてください:
最初の引数898
はパラメーターに対応していますか、それとも可変引数パラメーターに対応していますか (そして のデフォルト値をit
使用するつもりですか)?42
it
コンパイラはあなたの意図を知ることができません!
ところで、@Johannes は良い点を指摘しましたmy_function()
。引数を渡さずに単純に呼び出すことができます。これは、デフォルトの引数を利用できる唯一の例です。
デフォルト パラメータの位置を変更すると、次のようになります。
void f(..., int p = 10); //illegal
それから、これはそもそも C++ では違法です。
繰り返しますが、自問してください。許可されている場合、これを次のように呼び出すことができます。
f(9879, 97897, 7897);
最後の引数7897
はパラメーターに対応していますか、それとも可変引数パラメーターに対応していますか (そして のデフォルト値をp
使用するつもりですか)?10
p
この場合も、コンパイラはあなたの意図を知ることができません。
はい、この関数宣言に技術的に問題はありませんが、関数を呼び出すときにコンパイラが警告できなかった間違いを犯しやすいため、この方法はお勧めしません。
デフォルトの引数を持つ最初の引数で、引数の提供を停止できます。デフォルトの引数が引き継がれるようにすると、可変引数リストはもちろん空になります。
名前付きパラメーター以外の引数を指定して、可変引数リストに入力することができます。この場合、デフォルトの引数は使用されません。
ご指摘のとおり、これが実際に役立つ実用的な状況があるかどうかは別の問題です。
void my_function(int it=42, ...){ /* va_list/start/arg/end code here */}
そのコードは、それがどのように見えるかを正確に実行する必要があります。渡された最初のパラメーター(存在する場合)はパラメーターit
であり、残りは...
です。したがって、パラメーターを渡さない場合、it
パラメーターにはデフォルト値(42)が割り当てられ、(42it
に等しい)が関数に渡される唯一のパラメーターです。
このようなコードは...
、同様の状況での-terminated引数リストの他の使用法と同じように役立つ場合があります(リスクは同じ性質です)。
例:
次の関数を作成できます。
// DECLARATION:
// returns vector filled with items specified
std::vector<float> float_vector( size_t item_count = 0, ... /* floats */ );
// DEFINITION:
std::vector<float> float_vector( size_t item_count, ... )
{
std::vector<float> vec;
va_list ap;
va_start(ap, item_count);
for( ; item_count > 0; --item_count )
{
vec.push_back( va_arg(ap,float) );
}
va_end(ap);
return vec;
}
と同等float_vector()
であるため、明らかに空のベクトルを返しますfloat_vector(0)
。他のすべての場合float_vector
、引数の数が可変の通常の関数のように動作します。