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?
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.
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.
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++.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With