Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can default function arguments "fill in" for expanded parameter packs?

The following code fails to compile :

#include <iostream>

template<typename F, typename ...Args>
static auto wrap(F func, Args&&... args)
{
    return func(std::forward<Args>(args)...);
}

void f1(int, char, double)
{
    std::cout << "do nada1\n"; 
}

void f2(int, char='a', double=0.)
{
    std::cout << "do nada2\n"; 
}

int main()
{
    wrap(f1, 1, 'a', 2.); 
    wrap(f2, 1, 'a'); 
}
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

main.cpp: In instantiation of 'auto wrap(F, Args&& ...) [with F = void(*)(int, char, double); Args = {int, char}]':
main.cpp:22:20:   required from here
main.cpp:6:44: error: too few arguments to function
     return func(std::forward<Args>(args)...);

It seems that the rule about "parameter packs being last" is followed (at least in the declaration) and after the expansion a correct function call should be formed : f2 can either be called with 1, 2 or 3 arguments so the too few arguments being an error seems 'harsh'. It also doesn't look like a deduction problem (which would be my guess - but got shaky due to the error message)

Is this a missing feature or there's a violation from the Standard's point of view ?

like image 384
Nikos Athanasiou Avatar asked Jan 28 '15 16:01

Nikos Athanasiou


People also ask

Can functions have default arguments?

In C++ programming, we can provide default values for function parameters. If a function with default arguments is called without passing arguments, then the default parameters are used. However, if arguments are passed while calling the function, the default arguments are ignored.

What is default argument function?

In computer programming, a default argument is an argument to a function that a programmer is not required to specify. In most programming languages, functions may take one or more arguments. Usually, each argument must be specified in full (this is the case in the C programming language).


1 Answers

You aren't calling a function with default-arguments from the template.

You are calling a function-pointer, which points to a function expecting exactly 3 arguments, neither more nor less.

Of course the compiler complains bitterly about the missing third one.

You could do what you are trying to do there with a variadic functor, since C++14 even a lambda:

wrap([](auto&&... args){return f2(std::forward<decltype(args)>(args)...);}, 1, 'a'); 
like image 97
Deduplicator Avatar answered Oct 18 '22 13:10

Deduplicator