Можно ли сохранять указатели функций с аргументами, чтобы
запустить позже в C ++.
Да , это так.
Прежде всего, если вы уже используете C ++ 11 или более позднюю версию, вам не нужно повышать уровень, чтобы справиться с текущей проблемой.
Самый простой и интуитивно понятный подход - сделать все ваши функции лямбда-функцией (т.е. вернуть лямбда-выражения) и сохранить их в
std::queue<storableFunction> instruction;
Подробное описание лямбды вы найдете здесь: Что такое лямбда-выражение в C ++ 11?
Предоставление идеи storableFunction
хорошо, поскольку вы можете явно указывать тип указателя функции для каждой функции-члена, которую вы храните в modelObj
.
Однако, если вы хотите сохранить некоторые контейнеры STL, вам нужно использовать std::function
с некоторыми издержками на стирание типа , которые могут иметь дело с различные лямбда-функции , способные захватывать переменные в области видимости).
Вот пример кода с std::vector
#include <iostream>
#include <vector>
#include <functional>
int main()
{
int arg1 = 4;
std::string arg2 = "String";
std::vector<std::function<void()>> vecFunPtr
{
[](int arg1 = 1){ std::cout << arg1 << std::endl; },
[](float arg1 = 2.0f){ std::cout << arg1 << std::endl; },
[](double arg1 = 3.0){ std::cout << arg1 << std::endl; },
[&arg1, &arg2](){ std::cout << arg1 << " " << arg2 << std::endl; }
};
for(const auto& funs: vecFunPtr) funs(); // call the stored lambdas
return 0;
}
выход
1
2
3
4 String
В вашем случае, Renderer
можно записать следующим образом. Стоит отметить, что вам нужно сделать обходной путь для передачи различных аргументов функциям-членам (или, конечно, лямбда-захватам).
Примечание : Здесь вы найдете несколько советов, чтобы избежать проблем с производительностью из-за std::function
, которые могут быть полезны.
class Renderer
{
typedef std::queue<std::function<void()>> modelObj; // you might need modelObj for only this class
typedef std::function<void()> fFunPtr; // typedef for void(*)() using std::function
std::map<int, modelObj> models;
public:
// renderer functions can be written like returning a lambda
fFunPtr rFun1(int arg1) { return [](int arg1 = 1){ std::cout << arg1 << std::endl; }; }
fFunPtr rFun2(double arg1) { return [](float arg1 = 2.0f){ std::cout << arg1 << std::endl; }; }
// function to store them for latter use
void pushInputDataInstruction(const int id, const fFunPtr& funPtr)
{
models[id].push(funPtr);
}
};
int main()
{
Renderer objRender;
//do stuff
while(/*condition*/)
{
//do stuff
objRender.pushInstruction(/* id number, function pointer*/)
renderer.render();
}
return 0;
}