考虑以下代码(参见https://rextester.com/OAWUM62639):
#include <iostream>
#include <functional>
void foo( int x_ )
{
std::cout<< "Value: " << x_ << "\n";
}
void something( void *c )
{
auto *f = static_cast<std::function<void()>*>(c);
(*f)();
}
int main()
{
int x = 2;
std::function<void()> lmbd = [=](){ foo(x); }; // lambda with capture.
something( &lmbd ); // is this implicit conversion safe?
}
std::function<void()>
从 a到 a 的隐式转换是否void*
安全?
代码似乎按预期运行,但我不确定 C++11 标准在这种情况下施加的底层规则。
类似的问题是:如何将 std::function 对象传递给采用函数指针的函数?,但可接受的答案建议使用reinterpret_cast
。reinterpret_cast
在这种情况下是否有必要(请参阅https://rextester.com/ZUY69757)?
所有显示的代码都是安全的。
一般来说,对于任何类型的对象,将指向它的指针转换为,然后再转换回来使用它
T
是完全可以的。void*
static_cast
T*
这种接口的棘手之处在于:
强制转换为
void*
会丢失类型信息,但您必须强制转换回精确的原始类型才能使用指向的对象。强制转换为任何其他类型都可能导致未定义的行为。因此,通常这种接口唯一合理的行为是仅复制指针值本身并将指针传递回用户提供的上下文,该上下文知道实际类型。您将失去所有所有权语义。
void*
指针始终纯粹用于观察。它不具有任何所有权。因此,调用者必须确保实际对象(即)比指针lmbd
的任何使用都更持久。如果将指针存储在某个地方以供以后回调,这可能会变得很棘手。void*
something
something
与 C 交互时,有时需要这种接口,但对于纯 C++ 代码,无需这样做。模板或
std::function
直接传递是更好的解决方案。