Search code examples
c++copypromisemove

How to move a struct with promise inside it?


Recently I have read a part of "Concurrency in action" book concerning parallel quicksort implementation. I tried to check the code mentioned in the book and received an error on this part:

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

The compiler gives the error

std::promise::promise(const std::promise> &) : attempting to reference a deleted function.

The error is occured in generated copy constructor of listPart. I guess trying to move newLowerPart it tries to use deleted copy constructor of promise. I thought creating custom copy constructor would help, but even an attempt to move promise inside it gave me the same error. Could you help me to solve this problem? Thank you in advance


Solution

  • Remember, that correct handling rvalues requires special treatment. So your container should provide at least two versions of push:

    void push(const T& t); //'t' is coopied
    

    and

    void push(T&& t); //'t' is moved
    

    Also, you should define move constructor for listPart and forbid copying:

    Solution:

    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

    As I demonstrated, you shouldn't define copy constructor for listPart - it should either be deleted or (in case of pre-C++ 11) private with no implementation provided. That's because copying std::promise is not defined (its copy constructor is deleted), so copying instance of listPart is meaningless in this case.