如何移动内部有承诺的结构

How to move a struct with promise inside it?

本文关键字:承诺 结构 内部 何移动 移动      更新时间:2023-10-16

最近我读了一本关于并行快速排序实现的"并发在行动"一书。我试图检查书中提到的代码,但收到这部分的错误:

struct listPart
{
    list<T> data;
    promise<list<T>> promise;
};
listPart newLowerPart;
...
parts.push(move(newLowerPart));

编译器给出错误

std::p romise::p romise(const std::p romise> &) : try 以引用已删除的函数。

错误发生在 listPart 的生成复制构造函数中。我想试图移动 newLowerPart 它试图使用承诺的已删除复制构造函数。我认为创建自定义复制构造函数会有所帮助,但即使尝试在其中移动 promise 也会给我同样的错误。你能帮我解决这个问题吗?提前感谢您

问题可能出在您的parts容器实现上 - 它尝试复制 push 参数而不是移动它。下面是一个示例:

#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
}

请记住,正确处理右值需要特殊处理。因此,您的容器应至少提供两个版本的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))
    {  }
};

我认为创建自定义复制构造函数会有所帮助

正如我所演示的,您不应该为listPart定义复制构造函数 - 它应该被删除或(在 C++ 11 之前的情况下)私有而不提供实现。这是因为复制 std::p romise 没有定义(它的复制构造函数被删除),所以在这种情况下复制 listPart 的实例是没有意义的。