【问题标题】:error: use of deleted function ‘std::thread::thread(const std::thread&)'错误:使用已删除的函数‘std::thread::thread(const std::thread&)’
【发布时间】:2014-12-14 20:37:08
【问题描述】:

下面的代码按预期编译和工作。 结构(类)A 派生自 std::thread 并扩展为 int 更多。 main 代码创建一些线程,然后等待它们完成。

问题是,虽然代码在 struct A 中没有析构函数的情况下编译,但当析构函数未注释~A(){})时,我得到:

错误:使用已删除的函数'std::thread::thread(const std::thread&)'

我不知道为什么。

此外,我不明白为什么该代码同时适用于 push_backemplace_back,而根据我的理解,它不应该适用于 push_back

#include <iostream>
#include <thread>
#include <vector>

struct A : std::thread {
    int i;
    A(void f(const char*),const char* s,int i_) : std::thread{f,s},i{i_}{
        std::cout<<"A created"<<std::endl;
    }
    //~A(){} // uncomment to see error
};

void dosomething(const char* s){
    std::cout<<s<<std::endl;
}

int main(){
    std::vector<A> aa;
    aa.emplace_back(&dosomething,"hi people",3434);
    aa.push_back(A(&dosomething,"hi again people",777));
    aa.emplace_back(&dosomething,"hi again people",777);
    aa.push_back(A(&dosomething,"hi again people",777));

    for(auto& i:aa) i.join();
}

【问题讨论】:

  • 哪个编译器版本和选项?我怀疑这可能是编译器错误。
  • 至于为什么它与push_back一起工作,我相信你的结构A有资格自动生成移动构造函数,所以push_back将移动构造A中的来自你传入的临时向量。(注意有一个push_back(value_type &amp;&amp;) 重载!)
  • -g;-O0;-Wall;-std=c++14;-pthread 既使用 g++ 和 clang++ 也使用 -std=c++11
  • 在这里编译:goo.gl/fyGEz8 并在运行时抛出异常。
  • std::thread 是可移动的(A 在添加析构函数之前也是如此),但不可复制。

标签: c++ multithreading stdthread


【解决方案1】:

如果你想要析构函数,你可以通过添加来修复你的代码

A(A &&) = default;

恢复隐式移动ctor。


您的第一个问题是添加用户定义的析构函数会禁用 move 构造函数的隐式生成。

您看到的(误导性)错误是 STL 试图退回到无法移动的复制类型上,但由于 std::thread 故意不可复制而失败。

请参阅此 cppreference page 的有关隐式声明的移动构造函数的部分,以及此 other question 以了解一些相关的动机。

第二个混淆源是push_back 有一个移动重载,所以你的原始代码从一开始就没有复制,只是移动。如果您想证明这一点,请将 dtor 注释掉以使其再次工作,然后尝试 push_backA 的 const 引用。它会抱怨复制构造函数,这意味着其他 push_back 调用没有使用它。

【讨论】:

    猜你喜欢
    • 2014-01-10
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2014-11-25
    • 2014-04-16
    • 2020-12-21
    • 2020-12-15
    • 1970-01-01
    相关资源
    最近更新 更多