Reader Q&A: Generic lambdas

Tim just added this comment on the GotW #3 Solution blog post from last year:

Are you sure you can use auto in lambda like this?
I can not compile the code and I’m pretty sure auto does not work here.

If you mean auto as a lambda parameter type, such as

[](auto& s){ use(s); }

then yes, it’s (now) legal): That’s a new feature in currently-being-finalized C++14 standard, and it’s called “generic lambdas.” It means that the compiler-generated closure object’s

operator()

is a template, so you can call the same closure object multiple times with different types and get the templated operator stamped out for each set of types it’s called with.

Major compilers are now adding support for this. As of this writing, all of GCC, Clang, and Visual C++ have implemented the basic feature and you can get it in CTP/preview/alpha releases of each, such as GCC or Clang trunk, or Visual C++ November 2013 CTP. I can’t remember offhand which of those compilers have shipped an official release since adding it (VC++ has not) but they’ll all have it in their next released versions.

By the way, isn’t it wonderful that, for the first time in the history of C++, multiple major compilers are in pretty good sync like this, both with each other and with the standard? I think that’s awesome.

10 thoughts on “Reader Q&A: Generic lambdas

  1. note for gcc and clang, they might require compiler flag to enable cpp14 support(You can use Clang in C++1y mode with the -std=c++1y option.). and im personally not that impressed with compilers matching standard so nicely because i feel standard has done very little in 3 y so compiler vendors did not have a lot to do, except ms but they have been known to lag. :D
    if we dont get serialization, modules and concepts on cpp17 im gonna be very disappointed, but not surprised. :P

  2. In C++14 can we use default values for parameters of lambda functions?
    For example,

    auto f = [](int i, int j = 0){
            // Make something with i and j.
    }
    
    f(1); // calls f(1,0);
    f(1, 3); // calls f(1,3);
    

    It doesn’t compile with clang. Gcc doesn’t complain though (shouldn’t it complain?). I didn’t test with VC++.

  3. Generic lambdas are in clang 3.4, released 2014-01-06. It appears that that release supports the entire set of new C++14 features.

    Generic lambdas are supported in GCC’s 4.9 branch, which hasn’t yet been released.

  4. @bames Yes, clang actualy compiles it, my bad. But it shows the warning: “C++11 forbids default arguments for lambda expressions”. It happened to me recently, and as I usually avoid warnings, I changed my code and kept in mind that it was an error.

  5. Good Morning, This question is addressed to Herb Sutter. After reading a short bit about lambdas, I was reminded of an old question regarding wildcards. In this context, my question is a really basic one though. Are/were raw pointers considered synonymous with the wildcard, both in terminology and application?

  6. Hi,

    I had a few questions regarding the new generic lambda’s introduced by C++14 :

    1) Given return type deduction has been extended to regular functions in C++14 after lambdas supporting it since C++11, what limitations/problems prevented the committee from extending the syntax of generic lambdas to regular functions as well :

    std::size_t distance( auto const &cnt )
    {
       return std::distance(std::begin(cnt), std::end(cnt));
    }
    

    2) With the introduction of generic lambdas, is there any way to specify a deduced return type to be at least a reference ?

    struct A { };
    
    auto f = []( A &x ){ return x; }
    
    A a0;
    A &a1 = f(a0); // fails to compile, returns a copy.
    

    Of course, one could just specify the return type explicitly:

    auto f = []( A &x ) -> A & { return x; }
    

    But how to combine that with generic lambdas ?

    auto f = []( auto &x ) -> auto & { return x; } // Does this compile ?
    
  7. What is the type of a generic lambda? I know I can use “auto”, but sometimes it’s still useful to know the actual type.
    Is it convertible to std::function? In other words, can I write this?

    std::function<void(int& s)> f = [](auto& s){ use(s); };
    
  8. @Olivier Grant
    1) I suppose it’s because you have 2 alternatives:
    The old and somewhat lengthy version:

    template <typename T>
    std::size_t distance( T const &cnt )
    {
       return std::distance(std::begin(cnt), std::end(cnt));
    }
    

    The new, better version with concepts:

    std::size_t distance( Sequence const &cnt )
    {
       return std::distance(std::begin(cnt), std::end(cnt));
    }
    
  9. “im personally not that impressed with compilers matching standard so nicely because i feel standard has done very little in 3 y so compiler vendors did not have a lot to do”

    The standards committees and compiler writers have been working on many things in parallel. Some of them made C++14, some will make Technical Specifications to be released soon, and some will be in C++17, which is planned to be a new major release in less than half the time between the two previous major releases (C++98 and C++11).

Comments are closed.