Using template parameter in common lambda

GCC allows you to use the following syntax as an extension:

// a functional object that will add two like-type objects auto add = [] <typename T> (T a, T b) { return a + b; }; 

In n3418 , in 2012, a proposal for common lambdas, we see a syntax that allows:

 overload( []<class T>(T* p) {...}, 

However, since this is an extension, the syntax is clearly absent (or not allowed). In what situations can the above be useful when we have auto, and why is the syntax missing (or not allowed)?

+6
source share
1 answer

It seems to me that C ++ 14 polymorphic lambdas are simply more concise.

You can reproduce the effect of your pattern situation as follows:

 struct A {}; struct B {}; int operator+(A, A) { return 1; } int operator+(B, B) { return 2; } int operator+(A, B) { return 3; } int operator+(B, A) { return 4; } int main() { auto add = [](auto a, decltype(a) b) { return a + b; }; auto flexible_add = [](auto a, auto b) { return a + b; }; add(A{}, A{}); // works add(B{}, B{}); // works add(A{}, B{}); // doesn't work flexible_add(A{}, A{}); // works flexible_add(B{}, B{}); // works flexible_add(A{}, B{}); // works auto deref = [](auto *a) { return *a; }; int foo{}; A a; B b; deref(&foo); // works deref(&a); // works deref(&b); // works deref(foo); // doesn't work deref(a); // doesn't work deref(b); // doesn't work } 

Although there are many cases where the GCC extension is more capable, not only in your use case (where it fits more naturally). For example, regarding the non-piggy template options:

 #include <cstddef> #include <utility> #include <iostream> void print(std::initializer_list<std::size_t> il) { for (auto&& elem : il) std::cout << elem << std::endl; } int main() { auto indexed_lambda = [] <std::size_t... Is> (std::index_sequence<Is...>) { print({Is...}); }; indexed_lambda(std::make_index_sequence<5>{}); } 

Coliru

Complex generic parameter types:

 void foo() {} int main() { auto accept_no_args_fun_only = [] <typename R> (R (*)()) {}; accept_no_args_fun_only(foo); } 

Coliru

Variadics:

 #include <tuple> #include <vector> int main() { auto accept_vector = [] (std::vector<auto> &&) {}; // Unconstrained placeholder from Concept TS, but not variadic auto accept_tuple = [] <typename... Args> (std::tuple<Args...> &&) {}; accept_vector(std::vector{42}); accept_tuple(std::tuple{42}); } 

Coliru

I have not discussed the issue of including generic lambdas, but I can figure out whether to include such an extension when the current syntax covers most use cases, is concise and is suitable for the intent of lambdas, which is most often intended to create short code snippets.

EDIT

The GCC extension decided to become part of C ++ at the first meeting of ISO C ++ 20 standards :

+7
source

Source: https://habr.com/ru/post/976896/


All Articles