3

可変数の引数でオーバーロードを使用し続ける方法はありますか?

具体例は次のとおりです。

// Third party class
class ABC
{
public:
    void addValue(int);
    void addValue(float);
    void addValue(string);
    void execute(); // Any number of add values can be called before the execute
};

現在、このクラスのオブジェクトに値を追加したい場合、次のようにする必要があります: ABC *obj = new ABC(); obj->addValue(2.0); obj->addValue("文字列"); obj->execute();

クライアント コードですべての addValues を 1 行で実行できる方法はありますか?

次のようにマクロを使用してみましたが、引数の数ごとにマクロを定義する必要があります。

#define ADD_1_VALUES_TO_CLASS_ABC(obj, val1) { \
    obj->addValue(val1) }
#define ADD_2_VALUES_TO_CLASS_ABC(obj, val1, val2) { \
    obj->addValue(val1); obj->addValue(val2) }
#define ADD_3_VALUES_TO_CLASS_ABC(obj, val1, val2, val3) { \
    obj->addValue(val1) ; obj->addValue(val2); obj->addValue(val3) }

MACRO ADD_N_VALUES_TO_CLASS_ABC を定義して次のように呼び出す一般的な方法はありますか

ABC *obj = new ABC();
MACRO ADD_N_VALUES_TO_CLASS_ABC(obj, "String", 1.0, 4);
MACRO ADD_N_VALUES_TO_CLASS_ABC(obj, 1, 2.0, "String", 4.0, 3);

また、可変数の引数 va_args を使用すると、オーバーロードされた関数を呼び出すために必要な型情報が失われますか?

前もって感謝します。

4

3 に答える 3

2

準拠している C++11 コンパイラでは、可変個引数テンプレートを使用してそれを実現できます。

template<typename T>
void addValues(ABC& obj, T&& t)
{
    obj.addValue(forward<T>(t));
}

template<typename T, typename... Ts>
void addValues(ABC& obj, T&& t, Ts&&... ts)
{
    obj.addValue(forward<T>(t));
    addValues(obj, forward<Ts>(ts)...);
}

これはあなたがそれを使用する方法です:

ABC a;
add_values(a, 3, "hello", 4.5f);
于 2013-02-05T15:00:52.017 に答える
0

Variadic テンプレート (バージョン 4.3 以降の GCC で使用可能) と呼ばれる C++11 機能を使用すると、次のメンバー関数を追加できます。

void addValues(){}; // Base case.

template<class H, class... T>
void addValues(H&& head, T&&... tail)
{
    addValue(std::forward<H>(head));
    addValues(std::forward<T>(tail)...);
}

使用例:

addValues(1, 2.0, "String", 4.0, 3);

と同等です

addValue(1); addValue(2.0); addValue("String"); addValue(4.0); addValue(3);
于 2013-02-05T14:58:59.607 に答える
0

g++ バージョン 4.1.2 (かなり古い) を使用していると言うので、明らかに C++11 はオプションではありません。幸いなことに、それは必要ありません。可変個引数マクロを使用することは可能ですが、はるかに単純で洗練された C++ ソリューションは、cout のように考えて実行することです。

class AddTo {
  ABC *abc;
  public:
  AddTo(ABC *abc) : abc(abc) { }
  template<class T>
  const AddTo& operator<<(const T& val) const {
    abc->addValue(val);
    return *this;
  }
};

次に、これを次のように使用できます。

ABC *obj = new ABC();
AddTo(obj) << 1 << 2.0 << "String" << 4.0 << 3;
于 2015-02-17T19:45:58.590 に答える