将指向函数的指针转换为指向函数类型的不同指针的结果
Result of converting a pointer to function to different pointer to function type
(5.2.10/6( C++03 指向函数的指针可以显式转换为指向不同类型的函数的指针。调用函数的效果 通过指向与 不同的函数类型 (8.3.5( 的指针 函数定义中使用的类型未定义。除了 将类型为"指向 T1 的指针"的右值转换为"指针"类型 到 T2"(其中 T1 和 T2 是函数类型(并返回其原始状态 类型生成原始指针值,即此类指针的结果 未指定转换。[注:详见4.10 指针转换。
以下是我正在尝试做的事情,虽然很明显,将fp1
转换为fp2
的结果将产生原始指针,但同时标准中的措辞会"The result of such a pointer conversion is unspecified"
这是什么意思?
int f() { return 42; }
int main()
{
void(*fp1)() = reinterpret_cast<void(*)()>(f);
int(*fp2)() = reinterpret_cast<int(*)()>(fp1);
// Safe to call the function ?
fp2();
}
您误读了标准,"未指定"部分仅适用于其他转换:
除 [特殊情况] 外,未指定此类指针转换的结果。
该 [特殊情况] 是您转换回原始函数指针类型的一种,如您的示例所示。在这种特殊情况下,转换会生成原始指针值,因此可以像在示例中一样使用它。
仅对于其他转换,结果是未指定的。
是的,它是安全的。
reinterpret_cast
只允许您将一个指针强制转换为另一个指针,但它不保证任何安全性,并且使用此类指针的结果未指定,除非将其类型转换回其原始类型。
提到的标准引号指定,如果将一种类型的函数指针类型转换为另一种类型并尝试通过它调用函数,则结果是未定义的。
然而
reinterpret_cast
保证,如果将类型转换的指针转换回原始类型,则指针的格式正确。
您的代码尝试执行第二个操作,因此它是安全的。
是的,你很安全。您正在做的事情包含在"除了转换..."箱。
调用它的原因是允许您通过其他类型的函数指针传递函数指针。因此,您可以定义如下内容:
enum CallbackType {
eFuncPtrVoidReturningVoid,
eFuncPtrVoidReturningInt,
// ... more as needed ...
};
class CallbackRecord
{
public:
CallbackRecord(void (*cb)()): cbType(eFuncPtrVoidReturningVoid), cbFunc(cb)
{}
CallbackRecord(int (*cb)()): cbType(eFuncPtrVoidReturningInt),
cbFunc(reinterpret_cast<void (*)()>(cb)) {}
void operator()() const;
protected:
CallbackType cbType;
void (*cbFunc)();
};
void CallbackRecord::operator()() const
{
switch(cbType)
{
case eFuncPtrVoidReturningVoid:
(*cbFunc)();
break;
case eFuncPtrVoidReturningInt:
while((*reinterpret_cast<int (*)()>(cbFunc))())
;
break;
}
}
虽然你可以说"让所有回调都返回int
",但如果回调类型的数量超过两个,这将要求你为不符合调用约定的任何内容编写包装器。 允许这些函数指针类型转换为您提供了支持多种回调类型的替代方法,并使我们不需要将CallbackRecord
转换为模板。它还允许子类化或封送处理来替换上面的 switch
语句,而无需使用 virtual
方法。
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针