ampawd
ampawd

Reputation: 1010

Function default parameters are ignored

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

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Barry
Barry

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

Related Questions