Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is []<typename>(){} a valid lambda definition?

Tags:

I was experimenting with lambdas and compilers because of another question here on SO.
I've just realized (and it's perfectly normal indeed) that the following code is valid:

int main() {     auto l = [](){};     l.operator()(); } 

Actually the standard says that the closure type has a public inline function call operator and so on, thus it makes sense to be able to invoke it.

What I can't explain by looking at the standard (well, the working draft) is the fact that GCC (6.1) compiles the following snippet (clang 3.9 does not):

int main() {     auto l = []<typename>(){};     l.operator()<void>(); } 

No warnings, no errors. Is it valid code or should it be rejected by the compiler?

like image 697
skypjack Avatar asked Oct 09 '16 21:10

skypjack


People also ask

Which is a valid type for this lambda function?

A lambda expression is a function or subroutine without a name that can be used wherever a delegate is valid. Lambda expressions can be functions or subroutines and can be single-line or multi-line. You can pass values from the current scope to a lambda expression. The RemoveHandler statement is an exception.

Can lambda be templated?

From the various lambda improvements, template parameters for lambdas are my favorite ones. Lambdas support with C++20 template parameters, can be default-constructed and support copy-assignment, when they have no state, and can be used in unevaluated contexts.

Are functors the same as lambdas?

std::function<int(int,int)>; std::function<void(double)> ... Functors allow to write functional programs in C++. Lambdas are syntactic sugar to simplify this. With functors/lambdas classic patters from functional programming (e.g. map / filter /reduce) can be applied in C++.

Can lambdas be Inlined?

Inlinable lambdas can only be called inside inline functions or passed as inlinable arguments. noinline lambdas, however, can be manipulated in any way you like, including being stored in fields or passed around.


1 Answers

In N4140 5.1.2 [expr.prim.lambda], a Lambda expression is defined as

lambda-introducer lambda-declaratoropt compound-statement

where a "lambda-introducer" is the [], enclosing an optional "lambda-capture" and "lambda-declaratoropt" is the stuff starting with "( parameter-declaration-clause )".

[]<typename>(){} 

does not meet that requirement because there is something between the lambda introducer and the lambda declarator, so it is not a valid lambda expression.

Thus, your example code is not valid C++ and should be rejected by the compiler.


As this is also tagged gcc, I clicked through the list of GNU C++ extensions. I did not find any extension that would make the syntax in question legal in GNU C++.

However, according to Section 4 of this proposal (P0428R0), which proposes to add templated lambdas to C++, gcc got an experimental implementation of the aforementioned paper in 2009. This probably explains why gcc doesn't complain here.

like image 183
Baum mit Augen Avatar answered Oct 04 '22 03:10

Baum mit Augen