11

たとえば、次のようなものです。

#include <cstdarg>

void my_function(int it=42, ...)
{
     /* va_list/start/arg/end code here */
}

上記のコードは C++ で正確に何を意味するのでしょうか? G++ で問題なくコンパイルできます。これが役立つシナリオや、何をすべきかさえ想像できないことに注意してください。私はただ興味があります。

4

3 に答える 3

6
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使用するつもりですか)?42it

コンパイラはあなたの意図を知ることができません!

ところで、@Johannes は良い点を指摘しましたmy_function()。引数を渡さずに単純に呼び出すことができます。これは、デフォルトの引数を利用できる唯一の例です。


デフォルト パラメータの位置を変更すると、次のようになります。

void f(..., int p = 10); //illegal

それから、これはそもそも C++ では違法です。

繰り返しますが、自問してください。許可されている場合、これを次のように呼び出すことができます。

f(9879, 97897, 7897);

最後の引数7897はパラメーターに対応していますか、それとも可変引数パラメーターに対応していますか (そして のデフォルト値をp使用するつもりですか)?10p

この場合も、コンパイラはあなたの意図を知ることができません。

于 2011-04-30T13:55:21.887 に答える
5

はい、この関数宣言に技術的に問題はありませんが、関数を呼び出すときにコンパイラが警告できなかった間違いを犯しやすいため、この方法はお勧めしません。

デフォルトの引数を持つ最初の引数で、引数の提供を停止できます。デフォルトの引数が引き継がれるようにすると、可変引数リストはもちろん空になります。

名前付きパラメーター以外の引数を指定して、可変引数リストに入力することができます。この場合、デフォルトの引数は使用されません。

ご指摘のとおり、これが実際に役立つ実用的な状況があるかどうかは別の問題です。

于 2011-04-30T14:14:54.983 に答える
0
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、引数の数が可変の通常の関数のように動作します。

于 2011-04-30T23:43:53.623 に答える