假装packaged_task是可复制的
Pretending packaged_task is copy constructable
我一直在寻找解决方法来解决使用 std::function
擦除std::packaged_task
的问题。
我想做的是这样的:
#include <future>
#include <functional>
#include <iostream>
namespace {
std::function<void()> task;
std::future<int> make(int val) {
auto test = std::packaged_task<int()>([val](){
return val;
});
auto fut = test.get_future();
task = std::move(test);
return fut;
}
}
int main() {
auto fut = make(100);
task();
std::cout << fut.get() << "n";
}
它简洁明了,避免了自己重新实现很多机制。不幸的是,这实际上是不合法的std::packaged_task
因为它是仅移动的,而不是可复制的。
作为解决方法,我想出了以下内容,它根据std::promise
和std::shared_ptr
来实现事情:
#include <future>
#include <functional>
#include <iostream>
namespace {
std::function<void()> task;
std::future<int> make(int val) {
auto test = std::make_shared<std::promise<int>>();
task = [test,val]() {
test->set_value(val);
test.reset(); // This is important
};
return test->get_future();
}
}
int main() {
auto fut = make(100);
task();
std::cout << fut.get() << "n";
}
这"对我有用",但这实际上是正确的代码吗?有没有更好的方法来达到相同的净结果?
(请注意,第二个示例中std::shared_ptr
的生命周期对于我的实际代码很重要。显然,我将采取措施防止两次调用相同的std::function
)。
您的问题似乎源于类型不兼容:
std::function<void()> task; // Notice this is not a package_task
那么,您为什么期望这有效呢?
task = std::move(test); // when test is `std::packaged_task<int()>`
当我将任务更改为正确的类型时,它会按预期编译:
namespace {
std::packaged_task<int()> task; // Change this.
std::future<int> make(int val) {
auto test = std::packaged_task<int()>([val](){
return val;
});
auto fut = test.get_future();
task = std::move(test); // This now compiles.
return fut;
}
}
就个人而言,由于类型很重要,我会从test
中删除auto
。
namespace {
std::packaged_task<int()> task;
std::future<int> make(int val) {
std::packaged_task<int()> test([val](){return val;});
auto fut = test.get_future();
task = std::move(test);
return fut;
}
}
相关文章:
- 简单可复制与可简单复制
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 对于参加可复制和可移动类的访问者来说,应该有多少过载?
- 可变参数宏:无法通过"..."传递非平凡可复制类型的对象
- 为什么 std::atomic<std::string> 会给出微不足道的可复制错误?
- 我可以隐式地创建一个琐碎的可复制类型吗
- 是std::memcpy在不同的可复制类型之间的未定义行为
- 为什么一对常量是微不足道的可复制的,而对不是?
- 在一个微不足道的可复制结构中,移动语义应该实现吗?
- 防止作用域枚举可复制/可移动
- C :对象上的可复制视图
- 防御性地应用 std::move 到平凡可复制的类型是否不可取
- 为什么 std::function 本身是可复制构造的类型?
- C++不可复制的 lambda 的行为是可复制的
- 错误:无法通过'...'传递非平凡可复制类型的对象'class boost::filesystem::path'
- 不能让类是微不足道的可复制的。我做错了什么?
- 使用临时存储区复制普通的可复制类型:允许吗
- 使用realloc可以安全地重新分配琐碎的可复制对象的存储吗
- 为什么Boost.Asio处理程序必须是可复制的
- 我需要可复制的缓冲区,尽可能轻(例如,不初始化零)