I would like to store as a member variable a pointer to a function that may take a variable number of arguments of different types.
The basic construct I've been trying to use is along these lines
template <typename... Args>
using ArgsFuncPointer = void(*)(Args...);
template<typename... Args> void varArgsFunc(Args&&... args) { }
{
ArgsFuncPointer<int, float> funcPointer = varArgsFunc;
funcPointer(1, 2.0);
}
The problem is that varArgsFunc cannot be converted to ArgsFuncPointer<int, float>
See coliru for a (non-)working example.
Ultimately I would like to be able to do something like:
template <typename... Args> class Foo
{
public:
Foo(Args&&... args)
{
func(args);
}
VarArgsFuncPointer func;
}
UPDATE
It turns out the reason this wouldn't compile is due to the subtle difference in signature between ArgsFuncPointer and varArgsFunc. With ArgsFuncPointer the parameter pack is passed by rvalue reference, whereas with varArgsFunc the parameter pack is passed by value.
This works:
template <typename... Args>
using ArgsFuncPointer = void(*)(Args&&...);
template<typename... Args> void varArgsFunc(Args&&... args) { }
{
ArgsFuncPointer<int, float> funcPointer = varArgsFunc;
funcPointer(1, 2.0);
}
Working example here
The problem is that varArgsFunc is a template not a specific function, but ArgsFuncPointer<int, float> is a pointer to a specific function.
Untested, but you should be able to specify the actual function instance by specifying its template arguments:
ArgsFuncPointer<int, float> funcPointer = varArgsFunc<int, float>;
// ^^^^^^^^^^^^
// Must specify template arguments
On another note, I recommend that you use std::function instead of pointers to non-member functions. That will allow you to use std::bind or lambdas or just about any callable object.
Using std::function would be very similar to what you have now:
template <typename... Args>
using ArgsFuncPointer = std::function<void(Args...)>;
Then using a lambda you could do something like
ArgsFuncPointer<int, float> funcPointer = [](int i, float f)
{
varArgsFunc(i, f); // Call the real function
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With