Я хотел бы узнать, как создать абстракцию над классом Task, который может принимать объекты любой функции или функтора (вместе с его аргументами и т. Д. c) и сохранять его для последующего выполнения или распространять в некоторых потоках, независимо от того, .
Я немного поэкспериментировал с std::function
и шаблонными классами, но не смог. Поэтому я хотел бы сначала скомпилировать его, а затем запустить, чтобы ознакомиться с концепциями, а затем я буду искать более эффективный шаблон для своих нужд. Итак, вопрос в том, как мне сначала скомпилировать код для первого шага? Код показан ниже.
#include <iostream>
#include <string>
#include <queue>
#include <memory>
#include <functional>
class ITask
{
public:
virtual ~ITask() = default;
virtual void execute() = 0;
};
template<typename ReturnType, typename... Args>
class GameTask : ITask
{
explicit GameTask(std::function<ReturnType(Args...)>& func) :
func_(func)
{}
void execute()
{
// func(Args...); ??
}
private:
std::function<ReturnType(Args...)> func_;
};
// lets imitate some bigger classes with various methods
class BigClassA
{
public:
void func1(int a) { std::cout << ++a; }
int func2(const std::string& s) { std::cout << s; return b; }
int b = 4;
};
class BigClassB
{
public:
double func1(BigClassA& bca, int i) { bca.b += i; return 0.1; }
};
int main()
{
BigClassA a;
BigClassB b;
// perform immidiately by current main thread:
a.func1(2);
b.func1(a, 3);
a.func2("Hello");
//store under queue for later execution
std::queue<std::unique_ptr<ITask>> queue;
/* a.func1(2); */
// queue.push(std::make_unique<GameTask>( [&a](){ a.func1(2); } ));
/* b.func1(a, 3); */
// queue.push(std::make_unique<GameTask>( ));
/* a.func2("Hello"); */
// queue.push(std::make_unique<GameTask>( ));
while (queue.size())
{
queue.front()->execute();
queue.pop();
}
}
edit:
Варади c действительно был иголками здесь. Вот код, который я сейчас получаю:
#include <iostream>
#include <string>
#include <queue>
#include <memory>
#include <functional>
class ITask
{
public:
virtual ~ITask() = default;
virtual void execute() = 0;
};
class GameTask : public ITask
{
public:
GameTask(std::function<void()> func) : func_(func) {}
void execute() final
{
func_();
}
private:
std::function<void()> func_;
};
// lets imitate some bigger classes with various methods
class BigClassA
{
public:
void func1(int a) const { std::cout << ++a; }
int func2(const std::string& s) { std::cout << s; return b; }
int b = 4;
};
class BigClassB
{
public:
double func1(BigClassA& bca, int i) { bca.b += i; return 0.1; }
};
int main()
{
BigClassA a;
BigClassB b;
// perform immidiately by current main thread:
a.func1(2);
b.func1(a, 3);
a.func2("Hello");
//store under queue for later execution
std::queue<std::unique_ptr<ITask>> queue;
queue.push(std::make_unique<GameTask>( [&a]() { a.func1(2); } ));
queue.push(std::make_unique<GameTask>( [&a, &b]() {b.func1(a, 3); } ));
queue.push(std::make_unique<GameTask>( [&a]() { a.func2("Hello"); } ));
// delayed execution
while (queue.size())
{
queue.front()->execute();
queue.pop();
}
}
Я хотел бы услышать о каждом улучшении, которое я могу добавить.