C++ 什么';这是“什么?”;对",;键入擦除成员函数指针的方法?

C++ 什么';这是“什么?”;对",;键入擦除成员函数指针的方法?,c++,c++11,function-pointers,member-function-pointers,C++,C++11,Function Pointers,Member Function Pointers,我正在编写一个测试夹具,其中包括确保在适当的时间调用某些回调(实际上是Qt信号,但这对我的问题来说并不重要)。为了帮助实现这一点,我创建了一个helper类,用于记录回调(信号)触发到列表中时的情况 此列表需要能够记录触发的回调(信号)。我还希望不需要专门为此创建新的枚举。我的想法是将信号的地址记录为一个类型擦除指针,这样我就可以对照信号的地址检查记录 为了让自己更轻松,我将信号类型记录为: 模板 类信号类型 { 公众: SignalType()=默认值; SignalType(SignalTy

我正在编写一个测试夹具,其中包括确保在适当的时间调用某些回调(实际上是Qt信号,但这对我的问题来说并不重要)。为了帮助实现这一点,我创建了一个helper类,用于记录回调(信号)触发到列表中时的情况

此列表需要能够记录触发的回调(信号)。我还希望不需要专门为此创建新的枚举。我的想法是将信号的地址记录为一个类型擦除指针,这样我就可以对照信号的地址检查记录

为了让自己更轻松,我将信号类型记录为:

模板
类信号类型
{
公众:
SignalType()=默认值;
SignalType(SignalType const&)=默认值;
SignalType(SignalType&&)=默认值;
模板
信号类型(R(对象::*成员)(参数…)
:成员{reinterpret_cast(成员)}{}
模板
布尔运算符==(R(对象::*其他)(参数…)常量
{返回此->成员==重新解释(其他);}
私人:
void(Object::*member)()=nullptr;
};
这会从使用点“隐藏”类型擦除,因此我可以稍后编写:

QCOMPARE(event.type,&SomeObject::someMethod);
…不需要用演员阵容把它弄得乱七八糟

然而,GCC不高兴:

warning: cast between incompatible pointer to member types from ‘void (SomeObject::*)(...)’ to ‘void (SomeObject::*)()’ [-Wcast-function-type]
有没有一种方法可以让GCC感到高兴,而不用借助诊断
#pragma
s来简单地关闭警告?有没有其他“更好”的方法来实现这种特殊的类型擦除?(注意,我不需要调用
SignalType
封装的成员;我只需要能够测试是否相等。)



唉。应该搜索警告信息,而不是我想做的。从技术上讲,我猜这是的一个副本,但是它只询问如何消除警告,并且不清楚代码试图实现什么。因此,为了让我在这里学到一些有用的东西,请关注是否有其他“更干净”的方式来实现我的目标,而不是仅仅把它当作一个复制品,然后说“它无法修复”.

这里有一个解决方案,它拥有一个函数指针,可以比较相同类型的两个值,同时还充当运行时检查两个类型是否相同的
std::type_info
。它将函数指针存储在
char[]

#包括
模板
类信号类型
{
公众:
SignalType()=默认值;
SignalType(SignalType const&)=默认值;
信号类型和运算符=(信号类型常量&)=默认值;
模板
信号类型(R(对象::*成员)(参数…)无异常
:比较器(&比较来自\u void\u ptr的\u成员){
使用member_ptr_type=R(对象::*)(Args;

静态断言(sizeof(成员类型)您可以使用
std::any
。如果对指向成员类型的同一指针的任何转换失败,那么您就知道它不是同一个函数。如果成功,请比较这些值。@eerorika,不幸的是,这需要在GCC 4.8上编译;
std::any
,直到C++17…才可用。使用boost是绝对不可能的。ThaT说:“<代码> STD::什么< /代码>避免在内部有同样的问题?(或者它是吗?)GCC 4.8是相当古老的,也许考虑升级?为什么,如果你不介意<代码> MMECMP <代码>,那么你不应该介意<代码> MycPy < /C> > ING进入<代码> char数据[siZeof(Value:Obj::*)] /代码> @马修,你问了“正确的方法”。,但如果您不喜欢这个问题的答案,因为它使用虚拟函数和堆分配,那么您应该将该细节编辑到您的问题中。附加类型安全性的价值是什么?好吧,两个不同的成员函数无论如何都不能有相同的地址?@Matthew我做了一些思考,我认为
memcmp
只要它们不是都是空ptr,就会始终与
==
相同。两个指向成员函数的空指针可以与
memcmp
进行比较(请参阅),但可能会有更多的边缘情况,因此这是符合标准的安全方法