将void(*p)(SomeType*)转换为void(*p)(void*)是否安全?

Wei*_*ieh 10 c++

假设我有如下函数:

void fun(void* p){
    SomeType* p = reinterpret_cast<SomeType*>(p);
    ...
}
Run Code Online (Sandbox Code Playgroud)

api要求签名.我只是想知道我可以把它写成.

void fun(SomeType* p){
    ...
}
Run Code Online (Sandbox Code Playgroud)

把它投到void (*)(void*).

Sto*_*ica 9

虽然您可以将函数指针强制转换为其他函数指针,但是通过与其签名不匹配的指针调用函数是未定义的行为.你不能只是投射它并传递给API.

在C和C++ 03中,您必须创建一个与签名匹配的命名包装函数,并预先执行强制转换.在C++ 11及更高版本中,您可以使用无捕获的lambda(正确转换):

void fun(SomeType* p){
    ...
}

int main() {
  api_call(+[](void *v) {
    fun(static_cast<SomeType*>(v));
  });
}
Run Code Online (Sandbox Code Playgroud)

所述+前拉姆达在使其使用,只要它不捕获转换为常规函数指针.这不是严格需要的,但它使IMO的意图更加明确,没有太多的冗长.