I agree that there is no real "technical" restriction per se to allowing default arguments in lambdas to work in some cases. It wouldn't mangle your pointers and auto
, because the type of a function is not affected by default arguments. But that's also why this wouldn't be terribly practical.
Why?
Because default arguments, while part of a function signature, are not part of a function type:
[C++11: 1.3.17]:
signature
<function> name, parameter type list (8.3.5), and enclosing namespace (if any)
[ Note: Signatures are used as a basis for name mangling and linking. —end note ]
[C++11: 8.3.5/6]:
[..] The return type, the parameter-type-list, the ref-qualifier, and the cv-qualifier-seq, but not the default arguments (8.3.6) or the exception specification (15.4), are part of the function type. [ Note: Function types are checked during the assignments and initializations of pointers to functions, references to functions, and pointers to member functions. —end note ]
They are essentially a piece of syntactic sugar that are "activated" by the compiler being able to see the declaration of the function you use, and injected at the point of the function call:
#include <iostream>
void foo(int x = 5)
{
std::cout << x << '\n';
}
int main()
{
foo();
}
The default argument is "visible".
However, when you "hide" your function behind a pointer:
int main()
{
void (*bar)(int) = &foo;
bar();
}
- Error:
too few arguments to function
The type of bar
is correct, and the compiler knows that foo
has a default, but there's simply no direct syntax that exists to inform the compiler at the point of calling bar
that bar
is also foo
. Sure, in this trivial scenario it could figure it out by observing the assignment, but that's hardly justification for the wider argument.
For the same reason, default arguments stated only in a definition not visible at the call site are next to useless:
// a.h
void foo(int);
// a.cpp
#include "a.h"
#include <iostream>
void foo(int x = 5)
{
std::cout << x << '\n';
}
// main.cpp
#include "a.h"
int main()
{
foo();
}
- Error in main.cpp:
too few arguments to function
I imagine that this is the reason for:
[C++11: 8.3.6/4]:
[..] Declarations in different scopes have completely distinct sets of default arguments. [..]
We are allowed to "pile up" default arguments for class non-template member function definitions ([C++11 8.3.6/6]
); the example indicates that this default will still only apply in the same TU, which follows the behaviour we've seen above in my second code snippet.
So, if default arguments are not part of the function type, and must be unambiguously visible to the call site, then there are only a handful of trivially contrived corner-cases in which they would be useful for lambdas, which is when they are called in the same scope that they are created so the compiler can tractibly figure out how to "fill in" the default argument for the call to the lambda and, well, what is the point of that? Not a lot, I tell thee.