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("字符串"); 对象->执行();

有没有办法在客户端代码中我可以在 1 行中完成所有 addValues?

我尝试使用如下宏,但随后我必须为每个参数数量定义一个宏:

#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

既然您说您使用的是 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 回答
0

使用称为可变参数模板的 C++11 功能(在 GCC 4.3 版本中可用),您可以添加以下成员函数:

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 回答