Reputation: 1010
For this simplified piece of code I'm getting following error:
error: too few arguments to function std::cout << f();
int g(int a = 2, int b = 1)
{
return a + b;
}
template<class Func>
void generic(Func f)
{
std::cout << f();
}
int main()
{
generic(g);
}
I cannot clue the reason for why the default parameters of function f
are not passing into a function generic
. It behaves like f
doesn't have any default parameters ...
What's wrong there?
How do I forward default parameters correctly?
Upvotes: 18
Views: 1173
Reputation: 122830
I think the error message to this code quite nicely demonstrates why this isn't possible:
int g(int a=0,int b=0){return 0;}
typedef int (*F1)(int);
int main() {
F1 x = g;
}
error: cannot initialize a variable of type 'F1' (aka 'int (*)(int)') with
an lvalue of type 'int (int, int)': different number of parameters (1 vs 2)
F1 x = g;
^ ~
Even with default parameters, the type of g
is still
int (*) (int,int)
and that's what gets deduced when you instantiate the template.
If for some reason you cannot use C++11 or later (i.e. no lambdas, see Barry's answer) and you don't mind a little boilerplate, then you can use a function object:
#include <iostream>
struct g_functor {
int operator()(int a=0,int b=0){ return a;}
};
template <typename T> void foo(T t) { t(); }
int main() { foo(g_functor()); }
Note that you have to create an instance of g_functor
to pass it as a parameter.
Upvotes: 7
Reputation: 303357
g
may have default arguments, but the type of &g
is still int(*)(int, int)
, which is not a type that can be called with no arguments. Within generic
, we can't differentiate that - we've already lost the context about default arguments.
You can just wrap g
in a lambda to preserve the context:
generic([]{ return g(); });
Upvotes: 22