gpt4 book ai didi

c++ - 启动 std::thread 时无法将(函数指针)左值绑定(bind)到(函数指针)右值?

转载 作者:太空狗 更新时间:2023-10-29 19:53:51 24 4
gpt4 key购买 nike

我在使用 gcc 4.5.2 时遇到了一个有趣的问题。以下代码

#include<thread>
#include<iostream>

using std::cout;
void foo(int a){
cout<<a;
}

template <typename T>
void goo(void (*fn)(T),T c){
fn(c);
}

int main(void)
{
std::thread TH;
void (*ptr)(int)=foo;
TH= std::thread(goo<int>,ptr,1);
TH.join();

return 0;
}

.. 将无法在 gcc 4.5.2 上编译并出现 错误:无法将 'void(void (*)(int), int)' 左值绑定(bind)到 'void (&&)(void (*)(int) , int)' 后跟第二个错误 initializing argument 1 of 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void(void (*)(int), int), _Args = {void (*&)(int), int}]'

但是,当 template 被移除时,这段代码确实可以编译,它也可以使用 gcc 4.7.0 编译(使用 template)。

即使这是一个编译器问题,有人可以解释一下这样的错误是什么意思吗?我很乐意找到一种方法来进行绑定(bind)(即使这在 gcc 4.7 中是自动的)。

最佳答案

您偶然发现了两个错误。

GCC 的第一个错误是在“完美转发”-值类别扣除期间,它认为 goo<int>是一个右值。但是goo<int>实际上是一个左值。所以不是推导_Callablevoid(void (*)(int), int) , 它应该将其推断为 void(&)(void (*)(int), int) .然后引用折叠将产生左值引用作为参数类型,而不是 void(&&)(void (*)(int), int)就像它对您的 GCC 版本的错误处理一样。

在参数的实际初始化过程中,它还错误地拒绝了函数左值对右值引用参数的初始化(我不记得 GCC4.5 发布时工作草案的状态 - 但可能草案有那时候它的格式不正确)。对于函数类型表达式,标准允许使用函数类型的左值初始化对函数类型的右值引用。

将模板 id 解析为函数左值非常复杂,所以 GCC 弄错了我并不感到惊讶(参见 http://llvm.org/bugs/show_bug.cgi?id=7505http://llvm.org/bugs/show_bug.cgi?id=7505 两个例子,说明有多少规则相互作用看似简单的事情)。

关于c++ - 启动 std::thread 时无法将(函数指针)左值绑定(bind)到(函数指针)右值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10671134/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com