I'm trying to create class that can save function pointer, arguments and return type.
my class that saves function
// Here i can't pass temlpate because next step for me is creating array of CFnSaver ('std::vector<CFnSaver*>')
// template<typename T>
class CFnSaver
{
public:
// i can't use template here, compiler throw an error
// template<typename T>
std::function<int()> savedFn;
template<typename ... Args>
constexpr bool Save(void* pFn, Args ... args)
{
if (!pFn) return false;
// creating lambda function
auto lambdaFn = [pFn, args...]()
{
// I need to get function return type, not just hardcode 'int' (as i did)
using tempFn = int(*)(Args ...);
auto tempFunc = reinterpret_cast<tempFn>(pFn);
return tempFunc(args...);
};
// Here i can call original function and get result, e.g. '5', but i don't need it here
// auto res = lambdaFn();
// saving lambda to std::function
savedFn = lambdaFn;
return !!savedFn;
}
inline CFnSaver() {};
template<typename ... Args>
inline CFnSaver(void* pFn, Args ... args) { Save(pFn, args...); }
bool const operator ! () const { return(!savedFn); }
explicit operator bool() const { return !!savedFn; }
};
Usage example:
int printSum(int a, int b)
{
int sum = a + b;
printf_s("%d\n", sum);
return sum;
}
int main()
{
CFnSaver cfn(printSum, 2, 3);
// I need to get return of this function (now it's hardcoded to int)
auto res = cfn.savedFn();
return 0;
}
I also can create another version of my function, that passes another variable as ref. But i'm not comfortable with it.
void printSum(int a, int b, int& result)
{
int sum = a + b;
printf_s("%d\n", sum);
result = sum;
}
int main()
{
int result = 0;
CFnSaver cfn(printSum, 2, 3, result);
cfn.savedFn();
return 0;
}
I think i need another way to saving function or i'm missing out some way to do it, any help is appreciated.
P.s. sorry for my poor english.
I'm tried template class, template function, passing variables as ref.
Sadly, I don't think it is possible without using templates.
My advice would be to instead of using an array of saved functions create a lambda to call them and use that instead. The lambda could even take an array of bools specifying whether to call specific functions or not if that's necessary.
Edit:
If the return types are the same, or the functions can be grouped into lists with the same retun type std::bind
could be used. If :
std::vector<std::function<int()> vec {
AddNumbers, // AddNumbers(int, int) adds two numbers
std::bind(AddNumbers, std::placeholders::_1, 3) // Adds three to a number, usage example: vec[1](2); would return 5
}