有没有办法继续使用可变数量的参数进行重载?
具体示例如下:
// 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->执行();
有没有办法在客户端代码中我可以在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,我会丢失调用重载函数所需的类型信息吗?
提前致谢。
答案 0 :(得分: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);
答案 1 :(得分:0)
使用称为可变参数模板的C ++ 11特性(在4.3版的GCC中可用),您可以添加以下成员函数:
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);
答案 2 :(得分: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;