C++11 将回调函数传递给std::map的最佳方法是什么?

C++11 将回调函数传递给std::map的最佳方法是什么?,c++11,callback,stdmap,C++11,Callback,Stdmap,我试图处理以下代码,但程序崩溃: #include <iostream> #include <string> #include <map> using namespace std; typedef void (*callBackMethod)(string); class CTest { private: map<string, callBackMethod> mapMethod; void testMethod(string

我试图处理以下代码,但程序崩溃:

#include <iostream>
#include <string>
#include <map>

using namespace std;

typedef void (*callBackMethod)(string);
class CTest
{
private:
    map<string, callBackMethod> mapMethod;

    void testMethod(string msg)
    {
        cout << msg << endl;
    }
public:
    CTest()
    {
        addFunction("AA", (callBackMethod) &CTest::testMethod);
    }
    void addFunction(string funName, callBackMethod methodName)
    {
        mapMethod[funName] = methodName;
    }
    callBackMethod getMethod(string funName)
    {
        auto fun = mapMethod.find(funName);
        if(fun == mapMethod.end()) { return nullptr; }
        return fun->second;
    }
    void runFunction(string funName)
    {
        getMethod(funName)("test");
    }

};

int main()
{
    CTest test;
    test.runFunction("AA");

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
typedef void(*callBackMethod)(字符串);
类别测试
{
私人:
地图制图法;
void testMethod(字符串msg)
{

cout由于要使用成员变量,因此需要在
typedef
中以不同的方式指定签名:

在C++ Builder中,可以做到以下几点:

typedef void(__closure *callBackMethod)(string);
如果您这样做,我建议您保留一个指向成员所属对象的智能指针,以便在调用函数之前检查对象是否仍然有效,否则它将使应用程序崩溃

< > >代码>关闭> /COD>关键字是一个C++ Builder扩展,以满足使用完全限定成员名称< /P>的要求。 要处理全局函数和成员函数,我们有以下功能:

typedef void(__closure *callBackMethodMember)(string);
typedef void (*callBackMethodGlobal)(string);

/* And then on 2 overloaded functions */
void addFunction(string funName, callBackMethodMember methodName) {}
void addFunction(string funName, callBackMethodGlobal methodName) {}

如果需要同时指向
CTest
成员函数和自由函数,则可以使用

#包括
#包括
#包括
#包括
使用名称空间std;
使用callBackFunction=std::function;
void testFunction(字符串msg)
{

为什么你认为把一个指针指向成员函数是一个函数的指针?这是个好主意?@ T.C.那么你有什么建议?如果你想修改代码,可能的复制代码是什么?<代码>关闭/代码>是什么?是标准C++吗?我看到 C++关闭>代码是C++的Builder扩展到C++。所以如果你不是我们的话。ING C++ + Builder它将不可用。但是它可能做什么?可能有一个标准的链接。看看我提供的链接,它有一个很好的例子,它试图实现。也许看看STD::函数和STD::BINDYNEXY。你的代码工作。但是现在回调方法签名被隐藏了。我还需要从主回调方法。.例如:无效tst2(字符串s){所以你需要同时使用成员函数和非成员函数吗?是的。我需要同时使用成员函数和非成员函数。在这种情况下,我们要做的是让成员函数和非成员函数的所有函数都重载。这是非常旧的代码,可能不是最好的方法,但当时它工作得很好。我们现在转到并使用信号和插槽,我nstead.@獾,你有什么例子可以分享吗?
typedef void(__closure *callBackMethodMember)(string);
typedef void (*callBackMethodGlobal)(string);

/* And then on 2 overloaded functions */
void addFunction(string funName, callBackMethodMember methodName) {}
void addFunction(string funName, callBackMethodGlobal methodName) {}
#include <iostream>
#include <string>
#include <map>
#include <functional>

using namespace std;

using callBackFunction = std::function<void(string)>;

void testFunction(string msg)
{
    cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
}

class CTest
{
private:
    map<string, callBackFunction> mapMethod;

    void testMethod(string msg)
    {
        cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
    }
public:
    CTest()
    {
        addFreeFunction("AA", testFunction);
        addMemberFunction("BB", &CTest::testMethod);
    }
    void addMemberFunction(string funName, void(CTest::*methodName)(string))
    {
        using std::placeholders::_1;
        mapMethod[funName] = std::bind(methodName, this, _1);
    }
    void addFreeFunction(string funName, void(*methodName)(string))
    {
        mapMethod[funName] = methodName;
    }
    callBackFunction getMethod(string funName)
    {
        auto fun = mapMethod.find(funName);
        if(fun == mapMethod.end()) { return nullptr; }
        return fun->second;
    }
    void runFunction(string funName)
    {
        getMethod(funName)("test");
    }

};

int main()
{
    CTest test;
    test.runFunction("AA");
    test.runFunction("BB");

    return 0;
}