C++ 存储和调用具有不同签名的成员函数的无序_映射

C++ 存储和调用具有不同签名的成员函数的无序_映射,c++,templates,dynamic,C++,Templates,Dynamic,我正在创建一个名为MessageableObject的类,它可以在映射中注册自己的成员函数。通过调用sendMessage、提供返回类型作为模板参数、传递函数名以及参数作为可变参数,可以从外部调用这些函数。我以前见过类似的情况,只是函数不是存储它们的类的成员函数 下面是到目前为止我编写的代码,以及一个应该成功的测试用例 #包括 #包括 #包括 #包括 类MessageableObject { 使用_message_ptr=void(MessageableObject::*)(void); std

我正在创建一个名为MessageableObject的类,它可以在映射中注册自己的成员函数。通过调用sendMessage、提供返回类型作为模板参数、传递函数名以及参数作为可变参数,可以从外部调用这些函数。我以前见过类似的情况,只是函数不是存储它们的类的成员函数

下面是到目前为止我编写的代码,以及一个应该成功的测试用例

#包括
#包括
#包括
#包括
类MessageableObject
{
使用_message_ptr=void(MessageableObject::*)(void);
std::无序的\u映射\u消息\u映射;
公众:
MessageableObject()
{
}
模板
void addMessage(常量字符*名称,F func)
{
自动类型=std::type_索引(typeid(func));
_消息映射。插入(std::make_pair(名称,std::make_pair((_message_ptr)func,type));
}
模板
R sendMessage(常量字符*名称,参数&&…参数)
{
自动iter=\u message\u map.find(名称);
断言(iter!=\u message\u map.end());
自动类型=iter->秒;
auto func=重新解释强制转换(类型为.first);
断言(type.second==std::type_索引(typeid(func));
返回函数(标准::前进

非常感谢您提供的所有帮助。我对类型擦除和成员函数绑定不太了解。这是为了创建动态消息a-la unity engine的
GameObject.sendMessage
函数

更新:根据skypjack下面的回答,如果消息调用包含变量,上述解决方案将中断。可以通过将sendMessage中的
Args&&&…
更改为
Args…
,来解决此问题,但是这会带来一个新问题:如果消息添加到包含引用参数的映射中(例如
int-bar(int&,int)
),它将无法被隐式调用。调用
sendMessage(“bar”,x,2)
将按预期运行。

如果在文件顶部包含
,并使用此选项:

return (this->*func)(std::forward<Args>(args)...);
你把它投给:

void(MessageableObject::*)(void);
然后您将其转换为正确的类型,因为您调用它的方式如下:

obj.sendMessage<int>("bar", 1, 2);

类似的情况也会发生在错误的返回类型上。所有这些都是UB。因此,从我的角度来看,在生产环境中使用它的解决方案太弱了。

谢谢!这个解决方案可以编译并且确实有效。现在我只需要找到一个更健壮的解决方案来处理变量作为参数并避免UB。
void(MessageableObject::*)(void);
obj.sendMessage<int>("bar", 1, 2);
int x = 1;
obj.sendMessage<int>("bar", x, 2);
int (MessageableObject::*)(int &i, int j);