将虚拟复制构造函数添加到 std::packaged_task
Adding dummy copy constructor to std::packaged_task
我试图绕过 std::packaged_task 缺少复制构造函数的问题,以便我可以将其传递给 std::function(它只会被移动)。
我继承自 std::packaged_task 并添加了一个虚拟复制构造函数,如果我从不复制它移入的 std::function,我认为不应该调用它。
#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)());
我无法解析错误消息,所以我想知道是我做错了什么还是编译器失败了。
移动构造函数定义不正确,它将 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)
向上转换到基础 class 和 std::move
.
我试图绕过 std::packaged_task 缺少复制构造函数的问题,以便我可以将其传递给 std::function(它只会被移动)。
我继承自 std::packaged_task 并添加了一个虚拟复制构造函数,如果我从不复制它移入的 std::function,我认为不应该调用它。
#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)());
我无法解析错误消息,所以我想知道是我做错了什么还是编译器失败了。
移动构造函数定义不正确,它将 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)
向上转换到基础 class 和 std::move
.