【问题标题】:C++ thread error: "static_assert failed due to requirement" [duplicate]C++ 线程错误:“static_assert 由于要求而失败”[重复]
【发布时间】:2021-03-29 03:59:11
【问题描述】:

我刚开始学习多线程编程,我正在尝试更改主函数中声明的变量。我的主要功能如下所示:

#include <iostream>
#include <thread>

void foo(int &args)
{
    for (int i = 0; i < 10; i++)
    {
        args = rand() % 100;
    }
}

int main()
{
    int args;
    std::thread worker(foo, args);
    for (int i = 0; i < 10; i++)
    {
        std::cout << args << std::endl;
    }
    worker.join();
}

所以我希望 main 函数做的是将 args 作为引用并更改位于该内存地址上的值。然而,线程不喜欢这个想法。我从运行这段代码中收到的实际消息是:

/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/thread:135:2: error: static_assert failed due to requirement '__is_invocable<void (*)(int &), int>::value' "std::thread arguments must be invocable after conversion to rvalues"
        static_assert( __is_invocable<typename decay<_Callable>::type,
        ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
multThread.cpp:15:17: note: in instantiation of function template specialization 'std::thread::thread<void (&)(int &), int &, void>' requested here
    std::thread worker(foo, args);

还有更多,但我发现用错误消息完全填充这篇文章是多余的。我不确定是什么导致了这个问题,它是只接受右值的线程还是什么?提前感谢您的帮助。

【问题讨论】:

  • 因为您通过引用传递参数,所以可能会发生模拟读取和写入。那是未定义的行为。 Int 不是线程安全的。你应该使用原子或互斥体

标签: c++ multithreading


【解决方案1】:

要将引用参数传递给std::thread,您需要在调用站点将其转换为reference_wrapper,如下所示:

std::thread worker(foo, std::ref(args));

这是因为std::thread 复制了它的参数,而引用不能被复制。

【讨论】:

    【解决方案2】:

    您最常使用std::refstd::reference_wrapper 中发送参数:

    int args;
    std::thread worker(foo, std::ref(args));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2019-03-01
      • 2019-10-29
      • 2011-05-09
      相关资源
      最近更新 更多