如何移动其中包含承诺的结构?
How to move a struct with promise inside it?
最近我读了 "Concurrency in action" 书中关于并行快速排序实现的一部分。我试图检查书中提到的代码,并在这部分收到错误:
struct listPart
{
list<T> data;
promise<list<T>> promise;
};
listPart newLowerPart;
...
parts.push(move(newLowerPart));
编译器报错
std::promise::promise(const std::promise> &) : attempting
to reference a deleted function.
错误发生在listPart的生成拷贝构造函数中。
我想尝试移动 newLowerPart 它会尝试使用 promise 的已删除复制构造函数。我认为创建自定义复制构造函数会有所帮助,但即使尝试在其中移动承诺也给了我同样的错误。你能帮我解决这个问题吗?
提前谢谢你
请记住,正确处理右值需要特殊处理。所以你的容器应该至少提供两个版本的 push
:
void push(const T& t); //'t' is coopied
和
void push(T&& t); //'t' is moved
此外,您应该为 listPart
定义移动构造函数并禁止复制:
解决方案:
struct listPart
{
list<T> data;
promise<list<T>> promise;
listPart(const listPart&) = delete;
listPart(listPart&& source)
: data(std::move(source.data))
, promise(std::move(source.promise))
{ }
};
I thought creating custom copy constructor would help
正如我所演示的,您不应该为 listPart
定义复制构造函数——它应该被删除或(在 C++ 11 之前的情况下)私有而不提供任何实现。那是因为没有定义复制std::promise(它的复制构造函数被删除),所以在这种情况下复制listPart
的实例是没有意义的。
您的 parts
容器实施可能存在问题 - 它尝试复制 push
参数而不是移动它。
Here 是一个例子:
#include <list>
#include <future>
struct listPart
{
std::list<int> data;
std::promise<std::list<int>> p;
};
template<typename T>
class dummy_container{
T t_;
public:
void push_back(const T& t){
t_ = t;
}
void move_back(const T& t){
t_ = t;
}
void move_back(T&& t){
t_ = std::move(t);
}
};
int main() {
dummy_container<listPart> dc;
listPart lp;
//dc.push_back(std::move(lp)); // won't compile, function only handles const references
dc.move_back(std::move(lp)); // will compile, because it moves if possible
}
最近我读了 "Concurrency in action" 书中关于并行快速排序实现的一部分。我试图检查书中提到的代码,并在这部分收到错误:
struct listPart
{
list<T> data;
promise<list<T>> promise;
};
listPart newLowerPart;
...
parts.push(move(newLowerPart));
编译器报错
std::promise::promise(const std::promise> &) : attempting to reference a deleted function.
错误发生在listPart的生成拷贝构造函数中。 我想尝试移动 newLowerPart 它会尝试使用 promise 的已删除复制构造函数。我认为创建自定义复制构造函数会有所帮助,但即使尝试在其中移动承诺也给了我同样的错误。你能帮我解决这个问题吗? 提前谢谢你
请记住,正确处理右值需要特殊处理。所以你的容器应该至少提供两个版本的 push
:
void push(const T& t); //'t' is coopied
和
void push(T&& t); //'t' is moved
此外,您应该为 listPart
定义移动构造函数并禁止复制:
解决方案:
struct listPart
{
list<T> data;
promise<list<T>> promise;
listPart(const listPart&) = delete;
listPart(listPart&& source)
: data(std::move(source.data))
, promise(std::move(source.promise))
{ }
};
I thought creating custom copy constructor would help
正如我所演示的,您不应该为 listPart
定义复制构造函数——它应该被删除或(在 C++ 11 之前的情况下)私有而不提供任何实现。那是因为没有定义复制std::promise(它的复制构造函数被删除),所以在这种情况下复制listPart
的实例是没有意义的。
您的 parts
容器实施可能存在问题 - 它尝试复制 push
参数而不是移动它。
Here 是一个例子:
#include <list>
#include <future>
struct listPart
{
std::list<int> data;
std::promise<std::list<int>> p;
};
template<typename T>
class dummy_container{
T t_;
public:
void push_back(const T& t){
t_ = t;
}
void move_back(const T& t){
t_ = t;
}
void move_back(T&& t){
t_ = std::move(t);
}
};
int main() {
dummy_container<listPart> dc;
listPart lp;
//dc.push_back(std::move(lp)); // won't compile, function only handles const references
dc.move_back(std::move(lp)); // will compile, because it moves if possible
}