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

时间:2017-06-20 10:31:48

标签: c++

假设我有如下函数:

void fun(void* p){
    SomeType* p = reinterpret_cast<SomeType*>(p);
    ...
}

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

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

并将其投放到void (*)(void*)

1 个答案:

答案 0 :(得分:9)

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

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

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

int main() {
  api_call(+[](void *v) {
    fun(static_cast<SomeType*>(v));
  });
}

lambda前面的+会导致它被转换为常规函数指针,只要它没有捕获。它并不是严格需要的,但它使IMO的意图更加明确,没有太多的冗长。