C ++:如何传递通用函数名?

时间:2011-06-03 03:23:30

标签: c++ function

我正在用c ++构建一个程序,用户可以在达到用户定义条件时设置要调用的函数。我对c ++只有一点经验。

我知道如何在python中执行此操作。您只需定义函数并将所述函数的名称放入结构中(我总是使用字典)。当您使用该功能时,您将拨打类似于:

的电话
methods = { "foo" : foo, "bar" : bar } 
choice = input("foo or bar? ")
methods[choice]()

关于如何在c ++中解决此问题而不必对所有内容进行硬编码的任何想法?

4 个答案:

答案 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)

您可以查看函数指针:

http://www.newty.de/fpt/intro.html

答案 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;