我想这可以被描述为“插件架构”问题。
目前我有一个用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文件中必需的函数定义。
这是最好的方法吗?有没有更好的方法,或者是最好的选择,只是继续像我一样,并在创建时手动添加功能?我不会创建巨大的数量的这些,也不是我经常创建它们,但是自动化过程感觉不容易出错。我也希望能够将此代码提供给同事,并希望他能够添加功能而无需在其余文件中进行处理。
答案 0 :(得分:3)
您可以使用valarray
,其中std::map<std::string, FUNCPTR>
是函数指针的别名。例如:
FUNCPTR
正如@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)访问时间。