gpt4 book ai didi

c++ - 使用 `std::thread`的成员函数 `std::ref(*this)`编译失败

转载 作者:行者123 更新时间:2023-11-30 01:47:35 29 4
gpt4 key购买 nike

我使用以下最小示例来重现当我尝试创建一个调用非静态成员函数来完成其工作的线程时遇到的编译器错误:

#include <thread>
#include <iostream>
class Worker
{
public:
Worker() : m_worker(&Worker::doWork, std::ref(*this), 1)
{}
std::thread m_worker;

void doWork(int a) { std::cout << a << std::endl; }
};

int main(int argc, char* argv[]) {
Worker k;
}

当使用 gcc4.8-gcc5.1 时编译失败,原因如下:

In file included from /usr/include/c++/4.8/thread:39:0,

from /tmp/gcc-explorer-compiler115614-69-rgangs/example.cpp:1:

/usr/include/c++/4.8/functional: In instantiation of 'struct std::_Bind_simple<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>':

/usr/include/c++/4.8/thread:137:47: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Worker::*)(int); _Args = {std::reference_wrapper<Worker>, int}]'

7 : required from here

/usr/include/c++/4.8/functional:1697:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>'

typedef typename result_of<_Callable(_Args...)>::type result_type;

^

/usr/include/c++/4.8/functional:1727:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>'

_M_invoke(_Index_tuple<_Indices...>)

^

Compilation failed

另一方面,Clang 似乎可以很好地编译这段代码。谁在这里是正确的,这是 gcc 中的一个错误(有公开的票吗?)?


编辑: 当使用 m_worker(&Worker::doWork, this, 1) 初始化线程时,gcc 可以很好地编译它。那么,在这种情况下使用 std::ref(*this) 是否合法?我想任何 std::ref() 都更通用。

最佳答案

你的 thread构造函数调用依赖于以下语义:

[C++14: 30.3.1.2/3]: Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_COPY ( std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.9.2) shall be a valid expression.

INVOKE是这样定义的:

[C++14: 20.9.2/1]: Define INVOKE (f, t1, t2, ..., tN) as follows:

  • (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;
  • ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;
  • t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;
  • (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types described in the previous item;
  • f(t1, t2, ..., tN) in all other cases.

如您所见,此处没有提供std::reference_wrapper<Worker>。 ,这就是std::ref(*this)给你。当然,衰减规则中的任何内容都没有帮助([C++14: 30.2.6/1])。

Clang 实际上有点仓促行事,似乎允许这样做,因为有一天它会符合标准,这要归功于我们自己的 Jonathan Wakely。归档 Library Working Group issue #2219 .但是,目前还没有。

无论如何,这整件事都没有实际意义。无需编写此代码。只需这样写:

Worker() : m_worker(&Worker::doWork, this, 1)

关于c++ - 使用 `std::thread`的成员函数 `std::ref(*this)`编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31417389/

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