在自定义类中包装std::packaged_task
wrapping std::packaged_task inside a custom class
我试图将std::packaged_task包装在另一个类中,以便与任务调度程序一起使用。
目前,除了std::未来支持之外,我已经把它全部搞定了。为了获得std::future支持,我发现我需要对它提供的get_future()函数使用std::packaged_task。
我一直在尝试一整天的各种方法来让这个工作,但我似乎无法正确声明和初始化packaged_task使用从std::bind返回值。我试图破译所有相关libstdc++函数的实现,如std::async, std::future, std::thread等,但没有运气。
下面的代码是不工作版本和工作版本的实现。要使其工作,取消注释两个/*——WORKS*/,并注释另一个相关行。
#include <vector>
#include <deque>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <iostream>
#include <chrono>
#include <functional>
#include <windows.h>
class task
{
private:
struct task_implementation_base
{
virtual void execute() = 0;
};
template <class callable>
struct task_implementation : public task_implementation_base
{
task_implementation(callable&& f) : /*m_task(std::forward<callable>(f)) WORKS*/m_task(f) { }
void execute() { m_task(); }
//callable m_task; // WORKS
std::packaged_task<typename result_of<callable>::type> m_task;
};
template <class callable>
std::shared_ptr<task_implementation<callable>> make_routine(callable&& f)
{
return std::make_shared<task_implementation<callable>>(std::forward<callable>(f));
}
public:
template <class callable, class... arguments>
task(callable&& f, arguments&&... args) : m_function(make_routine(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...))) {}
void operator()() { run(); }
void run() { m_function->execute(); }
private:
std::shared_ptr<task_implementation_base> m_function;
};
int testint(int i)
{
std::cout << "test6" << " :: ran from thread " << std::this_thread::get_id() << "n";
fflush(stdout);
return i+100;
}
void test(const char* text)
{
std::cout << text << " :: ran from thread " << std::this_thread::get_id() << "n";
fflush(stdout);
}
class testclass
{
public:
void print1() { test("test3"); }
void print2() { test("test4"); }
void print3(const char* text) { test(text); }
};
int main()
{
testclass testclass1;
testclass* testclass2 = new testclass;
task test1(test, "test1");
task test2([]() { test("test2"); });
task test3(&testclass::print1, &testclass1);
task test4(&testclass::print2, &*testclass2);
task test5(&testclass::print3, &*testclass2, "test5");
task test6(&testint, 1);
test1();
test2();
test3();
test4();
test5();
test6();
Sleep(2000);
return 0;
}
我认为问题是typename result_of<callable>::type
。我猜它没有正确地计算callable
函数的返回类型。
我在Windows 8 64bit
上使用c++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental)
。我怀疑错误是不相关的因为我想我只是想让这个工作错误的方式但这里是错误的粘贴路径:errors
std::packaged_task
不仅接受被调用函数的结果类型作为模板参数,而且还接受传递给被调用函数的参数类型。
你可以这样定义它们:
// somewhere
int foo(bool, int);
// somewhere else
std::packaged_task<int(bool, int)> p(foo);
要修复你的代码,你需要添加两个空括号对。我上面的解释也适用于std::result_of
。
std::packaged_task<typename std::result_of<callable()>::type()> m_task;
这只是对主题问题的回答。如何实现
示例简短实现:
template <typename Signature> /// <---- 1
class Task;
template <typename Res, typename... ArgTypes>
class Task<Res(ArgTypes...)> /// <---- 2
{
public:
template <typename Function>
explicit Task(Function&& callback)
: _task{std::forward<Function>(callback)}
{ }
void execute(ArgTypes... args) noexcept(false)
{
//...
_task(std::forward<ArgTypes>(args)...);
}
private:
std::packaged_task<Res(ArgTypes...)> _task;
};
不知道为什么第1步&2是必需的,但我做了相同的lib实现。也许有人可以扩展一下。
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 使用"Task"函数指针队列定义作业管理器
- Visual Studio C++ Project File CustomBuild Task: Filter Outp
- 如何将C std ::未来返回值调整到C#System.Threading.tasks.task
- C# Task.Run() vs. C++ std::async()
- C++ FOR LOOP ONLY task
- inline void addTask(Task task) vs inline void addTask(const Task &task)
- 为什么我会收到"variable 'std::packaged_task<int> task' has initializer but incomplete type"错误
- C++ -<Task> 删除堆上分配的任务数组时,将列表 l(或任何 STL 容器)添加为数据成员会导致错误
- "task"指令的"final"条款是否正确?
- 如何在后台进程上处理来自Windows任务管理器的"End Task"?
- 视觉工作室 2013 "A task was cancelled"
- 正在CDH4中获取mapreduce.task.partition
- 创建Task Then函数(类似std::future.then)
- 为什么不在pop之后运行task并返回true呢?
- Task of getline
- Tantamount of while(cin>>something){some task ;} in java?
- "typedef void (*task) ()"做什么?
- Glowcode内存使用量与Window Task Manager不同