Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

547
Views
is lambda capture allowed in c++20 function trailing return type and noexcept operator?

Simple code as below or godbolt has different results from gcc, clang and Visual Studio.

auto foo1(int n) -> decltype(([n]() { return n+1; }()))
// gcc error: use of parameter outside function body before '+' token
{
    return [n]() { return n+1; }();
}

auto foo2(int n) -> decltype(([&n]() { return n+1; }()))
// gcc error: use of parameter outside function body before '+' token
{
    return [&n]() { return n+1; }();
}

auto foo3(int n) -> decltype(([&]() { return n+1; }()))
// gcc error: use of parameter outside function body before '+' token
// gcc and clang error: non-local lambda expression cannot have a capture-default
// VS2022 17.1 warning C5253: a non-local lambda cannot have a capture default
{
    return [&]() { return n+1; }();
}

It seems that gcc does not allow any type of capture if the lambda is in function trailing return type (or noexcept(noexcept(...))). clang is OK with capture by value and capture by reference but not OK with capture default. Visual Studio up to 17.0 allows any type of capture. Visual Studio 17.1 gives a warning for capture default.

What is the correct behavior here? It seems gcc, clang and latest VS 17.1 all agree capture default is not allowed in trailing return type (or noexcept(noexcept(...))). But is it a correct design? It is very convenient to put the same expression in return statement, noexcept and trailing return type (often by a macro) if the function is one-liner. But it is not possible now if there is a lambda with capture (default?) in this expression.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

From [expr.prim.lambda.capture]/3:

A lambda-expression shall not have a capture-default or simple-capture in its lambda-introducer unless its innermost enclosing scope is a block scope ([basic.scope.block]) or it appears within a default member initializer and its innermost enclosing scope is the corresponding class scope ([basic.scope.class]).

Which means that captures such as [n], [&n] or [&] are not allowed in trailing return types or noexcept specifiers, but initialized captures such as [i = 1] are.

So GCC is right to reject the first two function definitions and GCC and Clang are right to reject the last one.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!