我正在用c ++构建一个程序,用户可以在达到用户定义条件时设置要调用的函数。我对c ++只有一点经验。
我知道如何在python中执行此操作。您只需定义函数并将所述函数的名称放入结构中(我总是使用字典)。当您使用该功能时,您将拨打类似于:
的电话methods = { "foo" : foo, "bar" : bar }
choice = input("foo or bar? ")
methods[choice]()
关于如何在c ++中解决此问题而不必对所有内容进行硬编码的任何想法?
答案 0 :(得分:22)
您可以使用函数指针的映射:
void foo() { }
void bar() { }
typedef void (*FunctionPtr)();
typedef std::map<std::string, FunctionPtr> FunctionMap;
FunctionMap functions;
functions.insert(std::make_pair("foo", &foo));
functions.insert(std::make_pair("bar", &bar));
std::string method = get_method_however_you_want();
FunctionMap::const_iterator it(functions.find(method));
if (it != functions.end() && it->second)
(it->second)();
答案 1 :(得分:8)
您的Python代码实际上直接转换为C ++:
# Python:
# Create a dictionary mapping strings to functions
methods = { "foo" : foo, "bar" : bar }
// C++:
// create a map, mapping strings to functions (function pointers, specifically)
std::map<std::string, void(*)()> methods;
methods["foo"] = foo;
methods["bar"] = bar;
# Python
choice = input("foo or bar? ")
// C++:
std::string choice;
std::cout << "foo or bar? ";
std::cin >> choice;
# Python:
methods[choice]()
// C++
methods[choice]();
Python的字典类似于C ++的map
。它们都是关联容器,将值从一种类型映射到另一种类型的值(在我们的例子中,字符串到函数)。
在C ++中,函数不是一流的公民,因此您不能在地图中存储函数,但可以将指针存储到函数中。因此,映射定义有点毛茸茸,因为我们必须指定值类型是“指向不带参数且返回void的函数的指针”。
在旁注中,假设您的所有功能都具有相同的签名。我们不能存储返回void的函数和在同一映射中返回int的函数,而不需要额外的技巧。
答案 2 :(得分:6)
您可以查看函数指针:
答案 3 :(得分:-1)
另一个选项是函数对象+继承:
#include <string>
#include <iostream>
#include <conio>
#include <exception>
//---------------------------------------------------------------------------
struct Method{
virtual ~Method(){}
virtual
void operator() (void)=0;
};
struct foo: public Method{
virtual ~foo(){}
virtual
void operator() (void){
std::cout << "this is foo\n";
}
};
struct bar: public Method{
virtual ~bar(){}
virtual
void operator() (void){
std::cout << "this is bar\n";
}
};
Method* getMethodByName(std::string methName){
if( methName == "foo" )
return new foo();
else if( methName == "bar" )
return new bar();
throw invalid_argument("Unknown method");
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
std::string choice;
std::cout << "foo or bar?\n";
std::cin >> choice;
boost::shared_ptr<Method> method = getMethodByName(choice);
(*method)();
getch();
return 0;
}
虽然这需要boost's smart pointer lib。使用vanilla C ++:
Method* method = getMethodByName( choice );
try{
(*method)();
delete method;
}
catch(...){
delete method;
}
getch();
return 0;