What is the need of template lambda introduced in C++20 when C++14 already has generic lambda?












47















c++14 introduced generic lambdas that made it possible to write following:



auto func = (auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");


It is very clear that this generic lambda func works just like a templated function func would work.



Why did the C++ committee decide to add template syntax for generic lamda?










share|improve this question




















  • 4





    What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

    – Some programmer dude
    2 days ago













  • I've been told this was an interesting use case.

    – Max Langhof
    2 days ago
















47















c++14 introduced generic lambdas that made it possible to write following:



auto func = (auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");


It is very clear that this generic lambda func works just like a templated function func would work.



Why did the C++ committee decide to add template syntax for generic lamda?










share|improve this question




















  • 4





    What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

    – Some programmer dude
    2 days ago













  • I've been told this was an interesting use case.

    – Max Langhof
    2 days ago














47












47








47


7






c++14 introduced generic lambdas that made it possible to write following:



auto func = (auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");


It is very clear that this generic lambda func works just like a templated function func would work.



Why did the C++ committee decide to add template syntax for generic lamda?










share|improve this question
















c++14 introduced generic lambdas that made it possible to write following:



auto func = (auto a, auto b){
return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");


It is very clear that this generic lambda func works just like a templated function func would work.



Why did the C++ committee decide to add template syntax for generic lamda?







c++ c++14 c++20






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago









JavaA

1711




1711










asked 2 days ago









coder3101coder3101

1,274815




1,274815








  • 4





    What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

    – Some programmer dude
    2 days ago













  • I've been told this was an interesting use case.

    – Max Langhof
    2 days ago














  • 4





    What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

    – Some programmer dude
    2 days ago













  • I've been told this was an interesting use case.

    – Max Langhof
    2 days ago








4




4





What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

– Some programmer dude
2 days ago







What if you need to use a different template type than for the arguments or return type? And what if it's needed inside the body?

– Some programmer dude
2 days ago















I've been told this was an interesting use case.

– Max Langhof
2 days ago





I've been told this was an interesting use case.

– Max Langhof
2 days ago












4 Answers
4






active

oldest

votes


















68














C++14 generic lambdas are a very cool way to generate a functor with an operator () that looks like this:



template <class T, class U>
auto operator()(T t, U u) const;


But not like this:



template <class T>
auto operator()(T t1, T t2) const; // Same type please


Nor like this:



template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please


Nor like this (although this gets a bit tricky to actually use):



template <class T>
auto operator()() const; // No deduction


C++14 lambdas are fine, but C++20 allows us to implement these cases without hassle.






share|improve this answer
























  • Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

    – Sebastian Mach
    yesterday






  • 4





    @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

    – Quentin
    yesterday



















21














Since you can use templated lambdas in C++20, you can restrict your types in an easier way than an SFINAE expression:



auto lambda = <typename T>(std::vector<T> t){};


This lambda will work only with vector types.






share|improve this answer





















  • 7





    How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

    – StoryTeller
    2 days ago











  • It is more an information about what C++20 add to the lambda expression than an answer to the question

    – Antoine Morrier
    2 days ago



















13














The proposal that was accepted into C++20 has a lengthy motivation section, with examples. The premise of it is this:




There are a few key reasons why the current syntax for defining
generic lambdas is deemed insufficient by the author. The gist of it is
that some things that can be done easily with normal function templates
require significant hoop jumping to be done with generic lambdas, or
can’t be done at all.The author thinks that lambdas are valuable
enough that C++ should support them just as well as normal function
templates.




Following that are quite a few examples.






share|improve this answer































    12















    The new "familiar template syntax" for lambdas introduced in C++20
    makes constructs such as for_types and for_range viable and way more
    readable compared to C++17 alternatives.




    (source: compile-time iteration with C++20 lambdas)



    Another interesting thing that can be done on both C++14 and C++17 generic lambdas is directly calling operator() by explicitly passing a template parameter:



    C++14:



       auto l = (auto){ };
    l.template operator()<int>(0);


    C++20:



      auto l = <typename T>(){ };
    l.template operator()<int>();


    The C++14 example above is quite useless: there's no way of referring to the type provided to operator() in the body of the lambda without giving the argument a name and using decltype. Additionally, we're forced to pass an argument even though we might not need it.



    The C++20 example shows how T is easily accessible in the body of the lambda and that a nullary lambda can now be arbitrarily templated. This is going to be very useful for the implementation of the aforementioned compile-time constructs






    share|improve this answer










    New contributor




    Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.




















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54126204%2fwhat-is-the-need-of-template-lambda-introduced-in-c20-when-c14-already-has-g%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      68














      C++14 generic lambdas are a very cool way to generate a functor with an operator () that looks like this:



      template <class T, class U>
      auto operator()(T t, U u) const;


      But not like this:



      template <class T>
      auto operator()(T t1, T t2) const; // Same type please


      Nor like this:



      template <class T, std::size_t N>
      auto operator()(std::array<T, N> const &) const; // Only `std::array` please


      Nor like this (although this gets a bit tricky to actually use):



      template <class T>
      auto operator()() const; // No deduction


      C++14 lambdas are fine, but C++20 allows us to implement these cases without hassle.






      share|improve this answer
























      • Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

        – Sebastian Mach
        yesterday






      • 4





        @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

        – Quentin
        yesterday
















      68














      C++14 generic lambdas are a very cool way to generate a functor with an operator () that looks like this:



      template <class T, class U>
      auto operator()(T t, U u) const;


      But not like this:



      template <class T>
      auto operator()(T t1, T t2) const; // Same type please


      Nor like this:



      template <class T, std::size_t N>
      auto operator()(std::array<T, N> const &) const; // Only `std::array` please


      Nor like this (although this gets a bit tricky to actually use):



      template <class T>
      auto operator()() const; // No deduction


      C++14 lambdas are fine, but C++20 allows us to implement these cases without hassle.






      share|improve this answer
























      • Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

        – Sebastian Mach
        yesterday






      • 4





        @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

        – Quentin
        yesterday














      68












      68








      68







      C++14 generic lambdas are a very cool way to generate a functor with an operator () that looks like this:



      template <class T, class U>
      auto operator()(T t, U u) const;


      But not like this:



      template <class T>
      auto operator()(T t1, T t2) const; // Same type please


      Nor like this:



      template <class T, std::size_t N>
      auto operator()(std::array<T, N> const &) const; // Only `std::array` please


      Nor like this (although this gets a bit tricky to actually use):



      template <class T>
      auto operator()() const; // No deduction


      C++14 lambdas are fine, but C++20 allows us to implement these cases without hassle.






      share|improve this answer













      C++14 generic lambdas are a very cool way to generate a functor with an operator () that looks like this:



      template <class T, class U>
      auto operator()(T t, U u) const;


      But not like this:



      template <class T>
      auto operator()(T t1, T t2) const; // Same type please


      Nor like this:



      template <class T, std::size_t N>
      auto operator()(std::array<T, N> const &) const; // Only `std::array` please


      Nor like this (although this gets a bit tricky to actually use):



      template <class T>
      auto operator()() const; // No deduction


      C++14 lambdas are fine, but C++20 allows us to implement these cases without hassle.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 2 days ago









      QuentinQuentin

      45.2k586141




      45.2k586141













      • Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

        – Sebastian Mach
        yesterday






      • 4





        @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

        – Quentin
        yesterday



















      • Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

        – Sebastian Mach
        yesterday






      • 4





        @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

        – Quentin
        yesterday

















      Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

      – Sebastian Mach
      yesterday





      Nice and concise. Just adding this: The first (same types) can be solved by (auto a, decltype(a) b) in C++14.

      – Sebastian Mach
      yesterday




      4




      4





      @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

      – Quentin
      yesterday





      @SebastianMach almost. With that solution b is non-deduced, and its argument will be implicitly converted to the type of a instead.

      – Quentin
      yesterday













      21














      Since you can use templated lambdas in C++20, you can restrict your types in an easier way than an SFINAE expression:



      auto lambda = <typename T>(std::vector<T> t){};


      This lambda will work only with vector types.






      share|improve this answer





















      • 7





        How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

        – StoryTeller
        2 days ago











      • It is more an information about what C++20 add to the lambda expression than an answer to the question

        – Antoine Morrier
        2 days ago
















      21














      Since you can use templated lambdas in C++20, you can restrict your types in an easier way than an SFINAE expression:



      auto lambda = <typename T>(std::vector<T> t){};


      This lambda will work only with vector types.






      share|improve this answer





















      • 7





        How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

        – StoryTeller
        2 days ago











      • It is more an information about what C++20 add to the lambda expression than an answer to the question

        – Antoine Morrier
        2 days ago














      21












      21








      21







      Since you can use templated lambdas in C++20, you can restrict your types in an easier way than an SFINAE expression:



      auto lambda = <typename T>(std::vector<T> t){};


      This lambda will work only with vector types.






      share|improve this answer















      Since you can use templated lambdas in C++20, you can restrict your types in an easier way than an SFINAE expression:



      auto lambda = <typename T>(std::vector<T> t){};


      This lambda will work only with vector types.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited yesterday









      Peter Mortensen

      13.5k1983111




      13.5k1983111










      answered 2 days ago









      Antoine MorrierAntoine Morrier

      1,764518




      1,764518








      • 7





        How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

        – StoryTeller
        2 days ago











      • It is more an information about what C++20 add to the lambda expression than an answer to the question

        – Antoine Morrier
        2 days ago














      • 7





        How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

        – StoryTeller
        2 days ago











      • It is more an information about what C++20 add to the lambda expression than an answer to the question

        – Antoine Morrier
        2 days ago








      7




      7





      How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

      – StoryTeller
      2 days ago





      How is consteval related to the new syntax? It's cool and all, but I don't get the relevance.

      – StoryTeller
      2 days ago













      It is more an information about what C++20 add to the lambda expression than an answer to the question

      – Antoine Morrier
      2 days ago





      It is more an information about what C++20 add to the lambda expression than an answer to the question

      – Antoine Morrier
      2 days ago











      13














      The proposal that was accepted into C++20 has a lengthy motivation section, with examples. The premise of it is this:




      There are a few key reasons why the current syntax for defining
      generic lambdas is deemed insufficient by the author. The gist of it is
      that some things that can be done easily with normal function templates
      require significant hoop jumping to be done with generic lambdas, or
      can’t be done at all.The author thinks that lambdas are valuable
      enough that C++ should support them just as well as normal function
      templates.




      Following that are quite a few examples.






      share|improve this answer




























        13














        The proposal that was accepted into C++20 has a lengthy motivation section, with examples. The premise of it is this:




        There are a few key reasons why the current syntax for defining
        generic lambdas is deemed insufficient by the author. The gist of it is
        that some things that can be done easily with normal function templates
        require significant hoop jumping to be done with generic lambdas, or
        can’t be done at all.The author thinks that lambdas are valuable
        enough that C++ should support them just as well as normal function
        templates.




        Following that are quite a few examples.






        share|improve this answer


























          13












          13








          13







          The proposal that was accepted into C++20 has a lengthy motivation section, with examples. The premise of it is this:




          There are a few key reasons why the current syntax for defining
          generic lambdas is deemed insufficient by the author. The gist of it is
          that some things that can be done easily with normal function templates
          require significant hoop jumping to be done with generic lambdas, or
          can’t be done at all.The author thinks that lambdas are valuable
          enough that C++ should support them just as well as normal function
          templates.




          Following that are quite a few examples.






          share|improve this answer













          The proposal that was accepted into C++20 has a lengthy motivation section, with examples. The premise of it is this:




          There are a few key reasons why the current syntax for defining
          generic lambdas is deemed insufficient by the author. The gist of it is
          that some things that can be done easily with normal function templates
          require significant hoop jumping to be done with generic lambdas, or
          can’t be done at all.The author thinks that lambdas are valuable
          enough that C++ should support them just as well as normal function
          templates.




          Following that are quite a few examples.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 days ago









          StoryTellerStoryTeller

          94.6k12192256




          94.6k12192256























              12















              The new "familiar template syntax" for lambdas introduced in C++20
              makes constructs such as for_types and for_range viable and way more
              readable compared to C++17 alternatives.




              (source: compile-time iteration with C++20 lambdas)



              Another interesting thing that can be done on both C++14 and C++17 generic lambdas is directly calling operator() by explicitly passing a template parameter:



              C++14:



                 auto l = (auto){ };
              l.template operator()<int>(0);


              C++20:



                auto l = <typename T>(){ };
              l.template operator()<int>();


              The C++14 example above is quite useless: there's no way of referring to the type provided to operator() in the body of the lambda without giving the argument a name and using decltype. Additionally, we're forced to pass an argument even though we might not need it.



              The C++20 example shows how T is easily accessible in the body of the lambda and that a nullary lambda can now be arbitrarily templated. This is going to be very useful for the implementation of the aforementioned compile-time constructs






              share|improve this answer










              New contributor




              Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.

























                12















                The new "familiar template syntax" for lambdas introduced in C++20
                makes constructs such as for_types and for_range viable and way more
                readable compared to C++17 alternatives.




                (source: compile-time iteration with C++20 lambdas)



                Another interesting thing that can be done on both C++14 and C++17 generic lambdas is directly calling operator() by explicitly passing a template parameter:



                C++14:



                   auto l = (auto){ };
                l.template operator()<int>(0);


                C++20:



                  auto l = <typename T>(){ };
                l.template operator()<int>();


                The C++14 example above is quite useless: there's no way of referring to the type provided to operator() in the body of the lambda without giving the argument a name and using decltype. Additionally, we're forced to pass an argument even though we might not need it.



                The C++20 example shows how T is easily accessible in the body of the lambda and that a nullary lambda can now be arbitrarily templated. This is going to be very useful for the implementation of the aforementioned compile-time constructs






                share|improve this answer










                New contributor




                Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.























                  12












                  12








                  12








                  The new "familiar template syntax" for lambdas introduced in C++20
                  makes constructs such as for_types and for_range viable and way more
                  readable compared to C++17 alternatives.




                  (source: compile-time iteration with C++20 lambdas)



                  Another interesting thing that can be done on both C++14 and C++17 generic lambdas is directly calling operator() by explicitly passing a template parameter:



                  C++14:



                     auto l = (auto){ };
                  l.template operator()<int>(0);


                  C++20:



                    auto l = <typename T>(){ };
                  l.template operator()<int>();


                  The C++14 example above is quite useless: there's no way of referring to the type provided to operator() in the body of the lambda without giving the argument a name and using decltype. Additionally, we're forced to pass an argument even though we might not need it.



                  The C++20 example shows how T is easily accessible in the body of the lambda and that a nullary lambda can now be arbitrarily templated. This is going to be very useful for the implementation of the aforementioned compile-time constructs






                  share|improve this answer










                  New contributor




                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.











                  The new "familiar template syntax" for lambdas introduced in C++20
                  makes constructs such as for_types and for_range viable and way more
                  readable compared to C++17 alternatives.




                  (source: compile-time iteration with C++20 lambdas)



                  Another interesting thing that can be done on both C++14 and C++17 generic lambdas is directly calling operator() by explicitly passing a template parameter:



                  C++14:



                     auto l = (auto){ };
                  l.template operator()<int>(0);


                  C++20:



                    auto l = <typename T>(){ };
                  l.template operator()<int>();


                  The C++14 example above is quite useless: there's no way of referring to the type provided to operator() in the body of the lambda without giving the argument a name and using decltype. Additionally, we're forced to pass an argument even though we might not need it.



                  The C++20 example shows how T is easily accessible in the body of the lambda and that a nullary lambda can now be arbitrarily templated. This is going to be very useful for the implementation of the aforementioned compile-time constructs







                  share|improve this answer










                  New contributor




                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago









                  Toby Speight

                  16.4k133965




                  16.4k133965






                  New contributor




                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  answered 2 days ago









                  Hamza.SHamza.S

                  418210




                  418210




                  New contributor




                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.





                  New contributor





                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






                  Hamza.S is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54126204%2fwhat-is-the-need-of-template-lambda-introduced-in-c20-when-c14-already-has-g%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                      Alcedinidae

                      Origin of the phrase “under your belt”?