gpt4 book ai didi

c++ - 假装 packaged_task 是可复制构造的

转载 作者:太空狗 更新时间:2023-10-29 23:02:41 26 4
gpt4 key购买 nike

我一直在寻找 problem of type-erasing a std::packaged_task using std::function 的解决方法.

我想做的是这样的:

#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::promisestd::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;
}
}

关于c++ - 假装 packaged_task 是可复制构造的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27770237/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com