是否可以在运行时重载函数?

时间:2015-01-29 22:27:26

标签: c++ overloading

我想简化一个包含大约一百个这样的表达式的代码:

if( flag )
    AddData( key, some_number );
else
    AddData( key, error_description );

AddData重载为

bool AddData( int key, double value );
bool AddData( int key, const char * error );

我想像上面这样表达上面的代码:

AddData( key, flag? some_number : error_description );

当然,它不会编译,因为标志的值是在运行时确定的,而AddData签名需要在编译时确定。

将两个功能组合成类似

的功能
bool AddData( int key, bool flag, double value, const char * error );

并解决使用哪个参数以及忽略哪个参数会起作用,但它看起来不够漂亮。

因此问题:是否有可能以更合理的方式在运行时解决函数重载?

3 个答案:

答案 0 :(得分:2)

只需在函数中定义一个小助手,然后使用:

auto AddHelper = [](bool flag, int key, double value, const char* error) {
    return flag ? AddData(key, value) : AddData(key, error);
}

如果该标志实际上始终相同,那么这只是一个简单的改变:

auto AddHelper = [flag](int key, double value, const char* error) {
    return flag ? AddData(key, value) : AddData(key, error);
}

依靠编译器进行优化。

答案 1 :(得分:1)

使用多态而不是数百个ifs可能会更好。

而不是标志有一个多态基类来执行数据添加,而不是更改标志,而是选择了正确的派生类。

调用代码就是:

data_adder->add(key, value, error_description);

示例基类和派生类:

struct DataAdder {
  virtual void add(int key, double value, const char *error) = 0;
 protected:
  ~DataAdder(){};
};

struct ValueDataAdder : DataAdder {
  void add(int key, double value, const char*) override { AddData(key, value); }
};

struct ErrorDataAdder : DataAdder {
  void add(int key, double, const char* error) override { AddData(key, error); }
};

Live demo

答案 2 :(得分:0)

假设假设所有表达式中的符号都不能被分解出来,那么你得到的最好的就是

AddData(key, flag, some_number, error_description)

如果您可以考虑将flag应用于多个来电,那么您可以开始使用

这样的结构做得更好
Adder<flag>{}
  .AddData(key1, val1, error1)
  .AddData(key2, val2, error2)
  .AddData(...)
  .
  .

即。一个流利的&#39;记住每次都在if哪一侧的界面。