当前位置: 首页 > 知识库问答 >
问题:

为什么编译器抱怨std::thread参数在转换为rvalues后必须是invocable的?

牟辰龙
2023-03-14

为什么编译器抱怨如果线程函数分层被更改为ululethr(std::shared_ptr

gcc-10.1.0/include/c/10.1.0/thread:在“std::thread::thread”(\u Callable)的实例化中

136|typename衰变

有人能一步一步地给我解释一下吗。

如果能给我关于这个问题的任何提示,我将不胜感激。

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>

struct Base
{
    Base() { std::cout << "  Base::Base()\n"; }
    // Note: non-virtual destructor is OK here
    ~Base() { std::cout << "  Base::~Base()\n"; }
};

struct Derived: public Base
{
    Derived() { std::cout << "  Derived::Derived()\n"; }
    ~Derived() { std::cout << "  Derived::~Derived()\n"; }
};

void thr(std::shared_ptr<Base> p)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr<Base> lp = p; // thread-safe, even though the
                                  // shared use_count is incremented
    {
        static std::mutex io_mutex;
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << "local pointer in a thread:\n"
                  << "  lp.get() = " << lp.get()
                  << ", lp.use_count() = " << lp.use_count() << '\n';
    }
}

int main()
{
    std::shared_ptr<Base> p = std::make_shared<Derived>();

    std::cout << "Created a shared Derived (as a pointer to Base)\n"
              << "  p.get() = " << p.get()
              << ", p.use_count() = " << p.use_count() << '\n';
    std::thread t1(thr, p), t2(thr, p), t3(thr, p);
    p.reset(); // release ownership from main
    std::cout << "Shared ownership between 3 threads and released\n"
              << "ownership from main:\n"
              << "  p.get() = " << p.get()
              << ", p.use_count() = " << p.use_count() << '\n';
    t1.join(); t2.join(); t3.join();

    std::cout << "after joining the threads\n" <<
     "  p.get() = " << p.get() << ", p.use_count() " <<p.use_count() << std::endl;
    std::cout << "All threads completed, the last one deleted Derived\n";
}

输出:

Base::Base()
  Derived::Derived()
Created a shared Derived (as a pointer to Base)
  p.get() = 0x57be80, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
  p.get() = 0, p.use_count() = 0
local pointer in a thread:
  lp.get() = 0x57be80, lp.use_count() = 4  
local pointer in a thread:
  lp.get() = 0x57be80, lp.use_count() = 3
local pointer in a thread:
  lp.get() = 0x57be80, lp.use_count() = 2
  Derived::~Derived()
  Base::~Base()
after joining the threads
  p.get() = 0, p.use_count() 0
All threads completed, the last one deleted Derived

共有1个答案

薛高澹
2023-03-14

传递给std::线程构造函数的参数将被复制,然后作为右值转发给在新线程中运行的函数。因此,当您创建这样的std::线程时:

std::thread t1(thr, p)

参数p将被复制,然后作为右值转发。如果函数thr需要左值引用,则不能使用右值调用它。

静态断言告诉您不能调用thr(shared\u ptr

将引用传递到函数中的解决方案是使用函数创建引用包装对象:

std::thread t1(thr, std::ref(p))

这将创建一个std::reference_wrapper

这一点也在https://en.cppreference.com/w/cpp/thread/thread/thread#Notes

 类似资料:
  • 我正在尝试创建2个线程,它们与浮点数组一起工作。Howere编译器给了我这些错误: 我以为我忘记了dma线程的一些ctor参数,但事实并非如此。下面是我的代码: 我对lambda函数没有太多的经验,所以我不知道这里是否需要它们(并且很乐意避免它们)。谢谢你的建议!

  • 问题内容: 游乐场执行失败:MyPlayground.playground:109:22:错误:无效使用’()’调用非函数类型’[ClassA.ClassB.Type]’的值时,让didNotCompile = ClassA.ClassB ^ ~~ 问题答案: 如您所述,它可以使用以下语法: 但是,如果我们声明一个: 因此,我想说这是一个错误,也应该无需输入别名即可工作。 更新 :Apple 已经

  • 问题内容: 具有函数f(x,y,z),我需要求解约束f(x,y,z)= 0,然后对其进行绘制。我试图为每对(y,z)查找f(x,y,z)= 0的值x: Python(2.7.5)说“ TypeError:fsolve:’func’参数’func’的输入和输出形状不匹配。” 但是,如果我自己进行测试,它会具有相同的形状: 返回True。 为什么fsolve()抱怨? 问题答案: 期望参数和的返回值为

  • [Error]org.testng.testngException:无法将@Test annotated方法[testLoginPage]与[interface java.util.Map]插入。有关本机依赖项注入的更多信息,请参阅http://testng.org/doc/documentation-main.html#native-dependent ency-injection at org

  • 我知道不同的平台有不同的UI需求,但为什么我必须下载源代码并自己编译它呢?为什么我不能为我的平台下载一个可运行的版本?