根据字符串输入调用函数

时间:2015-05-18 16:59:11

标签: c++

我想这可以被描述为“插件架构”问题。

目前我有一个用c ++编写的代码,需要调用一个特定的函数(优化例程中的适应函数)。以前,这需要大量的代码重复,因为我发现错误是一个噩梦。所以 - 我已经设法压缩代码,除了各种适应度函数之外,我只有其中的一个,显然不能浓缩。

这些健身功能不会共享名称,也不需要。我设置它的方式是优化例程调用一个“主”适应度函数,该函数在输入字符串和函数的硬编码“名称”之间执行字符串比较。即:

FitFunc myMainFit(double* inp, int d) {
    double retVal;
    if (inName == "func1") {
        retVal = myFitOne(inp, d);
    } else if (inName == "func2") {
        retVal = myFitTwo(inp, d);
    // Other comparisons ...
    } else {
        std::cout << "Unknown Function" << std::endl;
        retVal = -1;
    }

    return retVal;
}

我想要做的是动态创建这些比较的方法,这样每次我有一个我想要使用的新函数时,我都不必更新一堆东西。

目前,我的健身功能都在一个目录中,并共享一些常见的命名特征,包括与它们包含的功能同名。 I.E - myFitTwo.cpp包含myFitTwo(double *,int)

我的想法是我可以在makefile中添加一个步骤,以便在编译时生成上面的代码块,以及包含的hpp文件中必需的函数定义。

这是最好的方法吗?有没有更好的方法,或者是最好的选择,只是继续像我一样,并在创建时手动添加功能?我不会创建巨大的数量的这些,也不是我经常创建它们,但是自动化过程感觉不容易出错。我也希望能够将此代码提供给同事,并希望他能够添加功能而无需在其余文件中进行处理。

1 个答案:

答案 0 :(得分:3)

您可以使用valarray,其中std::map<std::string, FUNCPTR>是函数指针的别名。例如:

FUNCPTR

Live on Ideone

正如@David Haim所提到的,你可以使用#include <iostream> #include <string> #include <map> typedef void(*FUNCPTR)(double*, int); // our typedef std::map<std::string, FUNCPTR> func_map; // some functions void f1(double*, int) {std::cout << "f1" << std::endl;} void f2(double*, int) {std::cout << "f2" << std::endl;} // call them via an invoking function void myMainFit(const std::string& which, double* ptr, int val) { if(func_map.find(which)!= func_map.end()) // indeed the function was added func_map[which](ptr, val); else { std::cerr << "Function \"" << which << "\" is not in the map!\n"; return; // or throw } } int main() { // add functions to the map func_map["first"] = &f1; func_map["second"] = &f2; myMainFit("first", nullptr, 42); myMainFit("second", nullptr, 20); myMainFit("inexistent", nullptr, 10); } (C ++ 11)来加快速度,因为后者是一个哈希表,它已经分摊了O(1)访问时间。