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
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.
The problem is likely with your parts container implementation - it tries to copy the push parameter instead of moving it.
Here is an example:
#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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With