Avoid two-line lambda (original) (raw)

January 3, 2024, 8:19pm 1

I’ve got a clang-format question regarding C++ lambdas. I’ve noticed new behavior with short, but not on-line lambdas after upgrading to Clang-Format 15.0.1. I call them “Two-line lambdas” below. Examples:

One-line lambdas

// good/unchanged
auto shortLambda= []() { doSomething(); }

Two-line lambdas:

// unwanted/new behavior
const auto mediumLambda = [some, args, here](More arguments)
{ return doSomething(some, args, here, arguments); }

// desired/unachievable behavior
const auto mediumLambda = [some, args, here](More arguments)
{
   return doSomething(some, args, here, arguments); 
}

Multiline Lambdas:

// good/unchanged
const auto longLambda= [some, args, here](Are here)
{
   auto result =doSomething(some, args, here, arguments); 
   return result;
}

Rational: “two line” if statements are not smashed together on two lines

// Good/unchanged
if (condition)
{
   doWhatever();
}

// Bad/unconfigured:
if (condition)
{ doWhatever(); }

I can get all lambdas to be multiline ones by setting AllowShortLambdasOnASingleLine : None - but I do want the ones that can fit on one line to fit on one line.

Relavent configurations:

# Basic
Language : Cpp
Standard : c++20
ColumnLimit : '110'

# Tabs
TabWidth : '3'
IndentWidth : '3'
UseTab : Never

# Braces/Parens (Allman style)
BreakBeforeBraces : Custom
BraceWrapping:
  AfterCaseLabel:  true
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterFunction:   true
  AfterNamespace:  true
  AfterObjCDeclaration: true
  AfterStruct:     true
  AfterUnion:      true
  AfterExternBlock: true
  BeforeCatch:     true
  BeforeElse:      true
  BeforeLambdaBody: true
  IndentBraces:    false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
Cpp11BracedListStyle : true
SpaceBeforeParens : ControlStatements
SpacesInParentheses  : false
SpaceInEmptyParentheses : false


# Functions
AlignAfterOpenBracket : Align
AllowShortBlocksOnASingleLine : false
AllowShortFunctionsOnASingleLine : Inline
BinPackArguments : true
BinPackParameters  : true
AllowAllParametersOfDeclarationOnNextLine : true
IndentWrappedFunctionNames : false
AlwaysBreakAfterReturnType : None
AlwaysBreakAfterDefinitionReturnType : None

# Lambdas
AllowShortLambdasOnASingleLine : All

Setting BeforeLambdaBody to false also works, but I want Allman style braces.

Edit: formatting

jtooker January 3, 2024, 10:57pm 2

I should say, I don’t believe this is possible and I would consider it a bug for those of us who prefer Allman style braces.

See also this stack overflow question I created and its responses.

philnik January 4, 2024, 2:43am 3

FWIW this looks a lot like a bug to me. The lambda clearly doesn’t fit on a single line, so the other configurations should kick in.