我收到了以下警告:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
这是因为我需要传递一个成员函数而不是普通函数作为参数。但程序运行正常。
我想要禁用此警告(Wno-bad-function-cast 对于C++无效),或者实现另一种方法来传递成员函数。
我收到了以下警告:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
这是因为我需要传递一个成员函数而不是普通函数作为参数。但程序运行正常。
我想要禁用此警告(Wno-bad-function-cast 对于C++无效),或者实现另一种方法来传递成员函数。
不要 忽视这个警告,你应该修改你的代码来处理这种情况。
成员函数指针 (void (MyClass::*)(byte)
) 和普通函数指针 (void (*)(byte)
) 是完全不同的。查看此链接。你不能直接将它们强制转换。否则会导致未定义行为或崩溃。
请看这里,它们的区别:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
现在你可能会觉得,foo(byte)
和MyClass::foo(byte)
具有相同的签名,那么为什么它们的函数指针不相同呢?这是因为,MyClass::foo(byte)
在内部被解析为某种程度上,如下所示:
void foo(MyClass* const this, byte);
现在你可以嗅出它们之间的区别。
将成员函数指针声明为:
void (MyClass::*ptr)(byte) = &MyClass::foo;
你需要使用ptr
与MyClass
对象一起使用,例如:MyClass obj;
obj.*ptr('a');
你不能将需要两个参数的函数传递到只接受一个参数的函数中。这是不可能的,别想了,就这样吧。调用者向你的函数传递一个参数。它不知道第二个参数,也不会将其传递给你的函数,无论你如何努力,都无法让它按照你想要的方式运行。
出于同样的原因,你也不能将非静态成员函数传递到期望常规函数的位置。成员函数需要一个对象来操作。调用你的函数的任何代码都不知道这个对象,没有办法将其传递给它,也没有办法使其使用正确的调用序列,考虑到对象。
接受用户函数的接口,而不带有用户可能想要传递给他的函数的其他数据,本质上是邪恶的。看看C标准库中的qsort()
函数。这是一个邪恶接口的例子。假设你想根据外部定义的排序方案对字符串数组进行排序。但它只接受一个比较函数,该函数接受两个值。如何将该排序方案传递给您的比较函数?你不能,所以如果你想让它工作,你必须使用一个邪恶的全局变量,附带所有的字符串。
另外,this 可能会有所帮助
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};
union
也不能帮助把一个指针视为另一个类型的指针。 - Ben Voigt