Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The validity of lambda expression with omitted parameter list in C++23

According to cppreference, both gcc and clang have completed the implementation of P1102R2 ("Down with ()!") recently, which means we can define lambda expressions more concisely in C++23.

But I found that they are inconsistent with a certain form:

auto l = []<auto> noexcept requires true {};

clang accepts this form, and gcc rejects its grammar.

Which compiler should I trust? Is this lambda well-formed or ill-formed in C++23?

Update:

Perhaps because of the pressure of public opinion, clang quickly fixed the 49736 within five days after I reported it.

As I tried further, I accidentally found out that gcc also rejected the following valid form, which made me report the 99850 and it was fixed after 2 weeks.

auto l = []<auto> requires true -> void {};
like image 627
康桓瑋 Avatar asked Mar 27 '21 16:03

康桓瑋


People also ask

What is the correct syntax for lambda expression in C++11?

Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };

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.

What is the correct statement about lambda expression?

What is the correct statement about lambda expression? Explanation: Return type in lambda expression can be ignored in some cases as the compiler will itself figure that out but not in all cases. Lambda expression is used to define small functions, not large functions.

Is it mandatory to declare type of parameter in lambda expression?

A lambda expression is characterized by the following syntax. Following are the important characteristics of a lambda expression. Optional type declaration − No need to declare the type of a parameter. The compiler can inference the same from the value of the parameter.


Video Answer


1 Answers

Thanks for reminding me of how pointless this feature is.

The correct answer is: no, that's not a well-formed lambda. The grammar is defined in [expr.prim.lambda.general]:

enter image description here

In our case, to start with we have:

[]<auto> noexcept requires true {};
  • [] is the lambda-introducer
  • <auto> matches <template-parameter-list> and now we know we're the 2nd kind lambda-expression. So grammatically, we're need to follow with a requires-clause (optionally) then a lambda-declarator then a compound-statement.
  • noexcept does not match requires-clause, so now we're parsing a lambda-declarator. A lambda-declarator could start with (parameter-declaration-clause) but we don't have that, so we're just looking for lambda-specifiers. We consume the noexcept as part of noexcept-specifier.
  • requires true does not fit either attribute-specifier-seq or trailing-return-type so we have neither of those, and now we're done with lambda-specifiers so we're done with lambda-declarator. At this point, we're looking for a compound-statement. But we don't have that, so this is an error.

Basically, there are two spots you can put a requires-clause: either directly after the template parameters or, if we have function parameters, after the lambda-specifiers after the function parameters. So this works:

[]<auto> requires true noexcept {};

as does this:

[]<auto>() noexcept requires true {};

as does this:

[]<auto> requires true () noexcept requires true { };

But not the one in OP.

Also, don't write this.

like image 73
Barry Avatar answered Oct 08 '22 10:10

Barry