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

use*_*779 9 c++ multithreading stdthread

下面的代码编译并按预期工作.结构(类)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();
}
Run Code Online (Sandbox Code Playgroud)

Use*_*ess 12

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

A(A &&) = default;
Run Code Online (Sandbox Code Playgroud)

恢复隐含的移动ctor.


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

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

请参阅此cppreference页面关于隐式声明的移动构造函数的部分,以及针对某些相关动机的另一个问题.

第二个混乱的来源是push_back移动过载,因此您的原始代码从不首先复制,只是移动.如果你想证明这一点,请将dtor注释回来,使其再次工作,然后尝试对push_back一个const引用A.它会抱怨复制构造函数,这意味着其他push_back调用没有使用它.