- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想写一个类似于 ppltasks 的简单任务类。
我希望我的任务类可以创建如下任务:
1.CreateTask([=]{}).then([=]{...});
2.CreateTask([=]{ return X; }).then([=](UnknownType X){...});
但我想在任务中运行的函数可能有不同的类型:void、float、string 等。这里是关键点:
auto val = func(); // If func is a void function
prms->set_value(val); // here should be: func(); prms->set_value();
如何使用相同的 CreateTask 处理 void 函数和其他类型的函数?
以下是我的任务类的完整代码:
template<typename TType>
class Task
{
public:
Task(){};
std::future<TType> mTask;
template<typename F>
auto then(F func)->Task<decltype(func(mTask.get()))>
{
Task<decltype(func(mTask.get()))> task;
auto prms = make_shared<promise<decltype(func(mTask.get()))>>();
task.mTask = prms->get_future();
thread th([=]
{
auto val = func(mTask.get()); //
prms->set_value(val);
});
th.detach();
return task;
});
};
inline void CreateTask(F func) -> Task<decltype(func())>
{
Task<decltype(func())> task;
auto prms = make_shared<promise<decltype(func())>>();
task.mTask = prms->get_future();
thread th([=]
{
auto val = func();
prms->set_value(val);
});
th.detach();
return task;
}
最佳答案
让我们通过关注点分离来解决这个问题。
首先,将一个可调用对象的输出通过管道传输到另一个可调用对象的问题:
template<class Index>
auto get_nth( Index ) {
return [](auto&&...args)noexcept(true)->decltype(auto) {
return std::get<Index::value>(
std::forward_as_tuple( decltype(args)(args)... )
);
};
}
template<class F>
struct pipeable_t;
template<class F>
pipeable_t<std::decay_t<F>> make_pipe(F&&);
struct is_pipeable {
template<
class Lhs, class Rhs,
std::enable_if_t<
std::is_base_of<is_pipeable, std::decay_t<Lhs>>{}
|| std::is_base_of<is_pipeable, std::decay_t<Rhs>>{}
, int> = 0
>
friend
auto operator|( Lhs&& lhs, Rhs&& rhs ) {
auto pipe_result=
[lhs = std::forward<Lhs>(lhs), rhs=std::forward<Rhs>(rhs)]
(auto&&...args)mutable ->decltype(auto)
{
auto value_is_void = std::is_same< decltype( lhs(decltype(args)(args)...) ), void >{};
auto pipe_chooser = get_nth( value_is_void );
auto pipe_execution = pipe_chooser(
[&](auto&& lhs, auto&& rhs)->decltype(auto){ return rhs( lhs( decltype(args)(args)... ) ); },
[&](auto&& lhs, auto&& rhs)->decltype(auto){ lhs( decltype(args)(args)... ); return rhs(); }
);
return pipe_execution( lhs, rhs );
};
return make_pipe( std::move(pipe_result) );
}
};
template<class F>
struct pipeable_t:is_pipeable {
F f;
pipeable_t( F fin ):f(std::forward<F>(fin)) {}
template<class...Args>
auto operator()(Args&&...args) const {
return f( std::forward<Args>(args)... );
}
template<class...Args>
auto operator()(Args&&...args) {
return f( std::forward<Args>(args)... );
}
};
template<class F>
pipeable_t<std::decay_t<F>> make_pipe(F&& f) { return {std::forward<F>(f)}; }
template<class T>
auto future_to_factory( std::future<T>&& f ) {
return [f=std::move(f)]() mutable { return f.get(); };
}
template<class T>
auto make_pipe( std::future<T>&& f ) {
return make_pipe( future_to_factory( std::move(f) ) );
}
我们可以make_pipe( some lambda )
现在它可以被送入更多的东西。
管道本身是可执行的和可管道化的。我们可以让任何可执行的东西成为管道,我们可以让 std::future
成为管道。
一旦有了这个,我们就根据它重写您的Task
:
struct dispatch_via_async {
template<class F>
auto operator()(F&& f)const {
return std::async( std::launch::async, std::forward<F>(f) );
}
};
template<class T, class Dispatch=dispatch_via_async>
class Task;
template<class F, class D=dispatch_via_async>
using task_type = Task<std::decay_t<std::result_of_t<F&&()>>, D>;
template<class F, class D=dispatch_via_async>
task_type<F, D> CreateTask(F&& func, D&& d={});
template<class T, class Dispatch>
class Task :
public is_pipeable, // why not?
private Dispatch
{
std::future<T> mTask;
Dispatch& my_dispatch() { return *this; }
public:
T operator()() { return mTask.get(); }
Task(){};
template<class F>
auto then(F&& func)&&
{
return CreateTask(
make_pipe(std::move(mTask)) | std::forward<F>(func),
std::move(my_dispatch())
);
}
template<class F, class D=Dispatch>
explicit Task( F&& func, D&& dispatch={} ):
Dispatch(std::forward<D>(dispatch))
{
mTask = my_dispatch()(
[func = std::forward<F>(func)]() mutable
-> decltype(func())
{
return func();
}
);
}
};
template<class F, class D>
task_type<F,D> CreateTask(F&& func, D&& d)
{
return task_type<F,D>( std::forward<F>(func), std::forward<D>(d) );
}
在这里,如果需要,我们小心地允许将调度程序(我们如何获得 future )传递到 Task
中。 .then
的延续将使用调度程序创建链接的 future 。
作为奖励,您现在拥有一个简单的流式操作链库。
请注意,我将基于 thread
的实现替换为基于 async
的实现,因为您的系统无法在程序完成之前正确等待线程终止,这会导致 undefined行为。您仍然可以将 Dispatcher
替换为使用线程的 Dispatcher。
在c++2a , Regular Void提案试图摆脱这个问题。我不知道它的工作效果如何。
上面没有构建在当前版本的 MSVC 中,因为 MSVC 不是一个合适的 c++14编译器,因为它的异步使用打包任务,它的打包任务将其任务存储在一个标准函数中,这导致异步错误地要求任务被 copyable 调用为 std::function
键入删除拷贝。
这打破了上面的代码,因为我们在我们的异步任务中存储了一个 std::future
,它不能被复制。
我们可以以适度的成本解决这个问题。最简单、最孤立的方法是将 future_to_factory
更改为:
template<class T>
auto future_to_factory( std::future<T>&& f ) {
return [f=std::make_shared<std::future<T>>(std::move(f))]() mutable { return f->get(); };
}
关于C++11/14 如何使用返回类型为 void 或其他类型的函数创建异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46772430/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!