What if the lambda expression of C++11 supports default arguments?

xmllmx picture xmllmx · Jan 7, 2013 · Viewed 11.8k times · Source

I think the following code is very handy and no harmful:

auto fn = [](bool b = false) -> int // NOT legal in C++11
{
    return b ? 1 : 0;
}; 

Why does C++11 explicitly prohibit default arguments of the lambda expression?

I just wonder the rationales and considerations behind.

I want to know "WHY" rather than "WHAT" the C++11 standard says.

Answer

Dietrich Epp picture Dietrich Epp · Jan 7, 2013

There is no real reason that lambdas can't have default arguments. However, there are two main ways to use lambdas, and only one of them would allow default arguments without changing the type system.

  1. You can call the lambda directly, or through a template. Default parameters would work fine in this case.

  2. You can call the lambda through std::function. Default parameters would not work without changing the type system.

My guess is that new functions that people write in C++11 will usually take std::function parameters because this way, the function won't have to be a template, or it won't have to be instantiated for every single lambda and functor that gets passed to it.

Why can't a std::function (or function pointer) take defaults?

It's not obvious what the type of such a function would be.

  • If it's std::function<int(bool)>, then how do you call it with the defaults? (You can't.)

  • If it's std::function<int(bool=false)>, then what types is it compatible with, and how does conversion work? Can you convert it to std::function<int()>? What about std::function<int(bool=true)>?

  • If it's something new like std::function<int(bool=default)>, then what types is it compatible with, and how does conversion work?

Basically, this isn't just a switch you can flip in the standard and make function pointers / std::function handle default arguments. Default arguments in normal functions are handled using information from the function's declaration, which is not available at the call site for a lambda or function pointer. So you would have to encode information about the defaults into the function type, and then work out all of the non-obvious rules for conversion and compatibility.

So you would have to come up with a compelling case for why such a feature would be added, and convince the committee.

So, why can't lambdas take defaults?

I haven't answered this question. But I don't think it would be a very useful feature to add. I would delete this answer if I could, but it's been accepted. I would downvote it if I could, but it's mine. C'est la vie.