如何移动其中包含承诺的结构?

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
}