【问题标题】:Why casting of function pointers not working as it is for the primitive types?为什么函数指针的转换不像原始类型那样起作用?
【发布时间】:2022-01-07 00:17:34
【问题描述】:
int* b = new int(40);
int c = *(int *)b;

上述演员工作正常。

但类似的转换不适用于函数指针

void abc(int a){
    cout<<a<<endl;
}

std::function<void(int)> callback = *(std::function<void(int)>*)abc; // this cast is not working

上面的代码有什么问题?

【问题讨论】:

  • 是什么让你认为void(*)(int)std::function&lt;int&gt;*
  • @Raildex 对于刚接触 C++ 或来自其他语言的人来说,假设函数是函数是函数并不是不合理的。事实上,C++ 有 3(4?)种半兼容的方式来表示一段可调用代码的句柄,这基本上是历史的偶然
  • 你根本不需要演员表:godbolt.org/z/zes3nW1WK
  • 你明白int c = *(int *)b;int c = (int)*b;的区别吗?

标签: c++ pointers type-conversion


【解决方案1】:

std::function&lt;void(int)&gt; 不是函数。这是一个带有operator() 的类。它有一个构造函数,您需要调用它来创建该类的实例。比如这样:

std::function<void(int)> callback = abc;

另一方面,这里:

int* b = new int(40);
int c = *(int *)b;

new int(40) 确实创建了一个 int 对象,b 是指向该对象的指针。演员 (int*)b 不做任何事情,因为 b 已经是一个 int*,您可以取消引用以将 int 的值分配给 c


我尽量保持简单,为了更准确地解释您的代码中实际发生的情况,我建议您参考以下答案:https://stackoverflow.com/a/70166958/4117728

【讨论】:

    【解决方案2】:

    您将b 转换为它已有的相同类型。这会导致静态转换,不会更改值。 b 的类型是 int* 并且你转换为 int*

    您将abc 转换为完全不同的类型。并且由于目标类型是不相关的,这会导致重新解释强制转换,并且通过重新解释的指针访问指向的对象(这是一个问题,因为它指向一个函数而不是一个对象)会导致未定义的行为。 abc 的类型是 void(int),它是一个函数类型,它隐式衰减到 void(*)(int),它是一个指向函数类型的指针。您将其转换为std::function&lt;void(int)&gt;*,它是一个指向对象类型的指针,其中对象类型是从类模板std::function 实例化的类类型。

    上面的代码有什么问题?

    • 使用 C 样式转换是错误的。不要这样做。
    • 将指针重新解释为不相关的类型是错误的。 std::function&lt;...&gt;* 不是函数指针。 std::function 不是函数。它是函数包装器的类模板。

    【讨论】:

    • 措辞上的挑剔:C 风格的演员表并不总是错误(但只要 c 风格的演员表是正确的,就可以用适当的演员表替换它,因此没有使用它的好理由)
    • @463035818_is_not_a_number 即使你“正确”地使用 C 风格类型转换也是错误的。
    • 好的,同意。我只是认为值得指出 wrongwrong 之间的细微差别;)
    猜你喜欢
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多