Добавление фиктивного конструктора копирования в std::packaged_task
Я пытаюсь обойти отсутствие в std::packaged_task конструктора копирования, чтобы я мог передать его в функцию std:: (которая будет только перемещена).
Я унаследовал от std::packaged_task и добавил фиктивный конструктор копирования, который, я полагаю, не должен вызываться, если я никогда не копирую функцию std::, в которую он был перемещен.
#include <iostream>
#include <future>
#include <functional>
#include <thread>
template <typename T>
class MyPackagedTask : public std::packaged_task<T()> {
public:
template <typename F>
explicit MyPackagedTask(F&& f)
: std::packaged_task<T()>(std::forward<F>(f)) {}
MyPackagedTask(MyPackagedTask&& other)
: std::packaged_task<T()>(std::move(other)) {}
MyPackagedTask(const MyPackagedTask& other) {
// Adding this borks the compile
}
};
int main()
{
MyPackagedTask<int> task([]() {return 0;});
auto future = task.get_future();
std::thread t(std::move(task));
t.join();
std::cout << future.get() << std::endl;
}
Компилируя это с помощью gcc 6.2.1, я получаю следующее сообщение об ошибке (только конечная часть, дайте мне знать, если вы хотите все это...):
/usr/include/c++/6.2.1/future:1325:6: error: invalid use of void expression
(*_M_result)->_M_set((*_M_fn)());
Сообщение об ошибке было для меня непонятным, поэтому я подумал, что я делаю что-то не так или компилятор выходит из строя.
1 ответ
Неверное определение конструктора перемещения, оно пересылается std::packaged_task<T()>&&
как MyPackagedTask&&
и это вызывает неправильный конструктор std::packaged_task<T()>
, Это является причиной ошибки компилятора, которую вы наблюдаете.
Правильный:
MyPackagedTask(MyPackagedTask&& other)
: std::packaged_task<T()>(static_cast<std::packaged_task<T()>&&>(other))
{}
Там static_cast<std::packaged_task<T()>&&>(other)
делает как переход на базовый класс и std::move
,