упаковка std :: packaged_task внутри пользовательского класса

Я пытаюсь обернуть std :: packaged_task в другой класс, чтобы использовать его вместе с планировщиком задач.

На данный момент у меня все работает, кроме поддержки std :: future. Чтобы получить поддержку std :: future, я понял, что мне нужно использовать std :: packaged_task для функции get_future (), которую он предоставляет.

Я целый день пробовал всевозможные способы заставить это работать, но мне кажется, что я не могу правильно объявить и инициализировать 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 функция.

я использую c++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental) на Windows 8 64bit, Я подозреваю, что ошибки не имеют значения, так как, я думаю, я просто пытаюсь сделать эту работу неправильным, но в любом случае вот пастбин для ошибок: ошибки

2

Решение

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;
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]