When compiling the following code:
#include <functional>
template <typename functionSignature>
class Class
{
std::function<functionSignature> func;
public:
Class(const std::function<functionSignature>& arg) : func(arg) {}
void callFunc() { func(); }
};
void f(const int i) {}
int main()
{
Class<void(const int)> a(std::bind(f, 10));
a.callFunc();
return 0;
}
The VS 2015 compiler generates the following error message at the sixth line:
error C2064: term does not evaluate to a function taking 0 arguments.
Now, I believe this is because the compiler thinks functionSignature
is not, well, a function signature; the same error happens when I instantiate and try to call operator()
on an std::function<int>
instead of std::function<int()>
, for instance.
How can I guarantee that the template argument will always be a function signature, so that I can call operator()
on the std::function
?
I suspect you want something like that:
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
std::function<R(P...)> func;
void callFunc(P... p) { func(p...); }
};
By using partial specialization that way you can easily define the type you want.
As an example, you can use it as:
Class<int(double)> c;
Of course, I noticed that you have no constructors for your class, so to invoke func
is not a good idea, but it's quite easy to define it and pass a proper function as an argument.
It follows a complete and working example where I've used the operator()
to invoke the function:
#include <functional>
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
Class(std::function<R(P...)> f): func{f} { }
void operator()(P... p) { func(p...); }
private:
std::function<R(P...)> func;
};
void fn() { }
int main() {
std::function<void()> f = fn;
Class<void()> c{f};
c();
}
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