下面的代码编译并按预期工作。
结构(类)A
派生自std::thread
,并以int
展开。
main
代码创建了一些线程,然后等待它们完成。
问题在于,虽然代码在struct A
中没有析构函数进行编译,但当析构函数取消注释(~A(){}
)时,我得到:
错误:使用已删除的函数'std :: thread :: thread(const std :: thread&)'
我不明白为什么。
此外,我不明白为什么代码适用于push_back
和emplace_back
,而根据我的理解,它不应该与push_back
一起使用。< / p>
#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();
}
答案 0 :(得分:11)
如果您想要析构函数,可以通过添加
来修复代码A(A &&) = default;
恢复隐式移动ctor。
您的第一个问题是添加用户定义的析构函数会禁用隐式生成 move 构造函数。
您看到的(误导性)错误是STL试图回退无法移动的复制类型,并因为std::thread
故意不可复制而失败。
请参阅此cppreference page有关隐式声明的移动构造函数的部分,以及此other question的相关动机。
第二个混淆的原因是push_back
有一个移动过载,所以你的原始代码从不首先复制,只是移动。如果你想证明这一点,请将dtor注释回来以便再次运行,然后尝试push_back
对A
的const引用。它会抱怨复制构造函数,这意味着其他push_back
调用没有使用它。