clang-format:如何将构造函数的初始值设定项列表的每个元素保留在单独的行上

iva*_*ukr 16 c++ llvm-clang clang-format

我有一个这样的 C++ 类:

class A {
public:
    A() :
        m_a(someValue1),
        m_b(someValue2),
        m_c(someValue3)
    {
    }

    // .... other class members

private:
    A m_a;
    B m_b;
    C m_c;
};
Run Code Online (Sandbox Code Playgroud)

使用 clang-format 格式化此代码后,我得到:

class A {
public:
    A() :
        m_a(someValue1), m_b(someValue2), m_c(someValue3)
    {
    }

    // .... other class members

private:
    A m_a;
    B m_b;
    C m_c;
};
Run Code Online (Sandbox Code Playgroud)

即构造函数中的初始化列表被格式化为单行,直到达到他们允许的最大行长度。

我的问题是如何告诉 clang-format 将每个元素保留在自己的行上,就像在格式化之前在我的原始代码中一样?我找不到任何合适的参数。我尝试将参数 AllowShortBlocksOnASingleLine(在我看来是最合适的)设置为 true 和 false,但这对此没有影响。那么有人可以建议如何实现这种格式吗?

这是我的 .clang 格式:

BasedOnStyle: Google
AccessModifierOffset: '-4'
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignEscapedNewlines: Left
AlignOperands: 'true'
AlignTrailingComments: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortBlocksOnASingleLine: 'true'
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: 'true'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
AlwaysBreakTemplateDeclarations: 'true'
BinPackArguments: 'true'
BinPackParameters: 'true'
BreakAfterJavaFieldAnnotations: 'true'
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
SplitEmptyFunction: true
BreakBeforeInheritanceComma: 'false'
BreakBeforeTernaryOperators: 'true'
BreakConstructorInitializers: AfterColon
BreakStringLiterals: 'true'
ColumnLimit: '100'
CompactNamespaces: 'false'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
ConstructorInitializerIndentWidth: '4'
ContinuationIndentWidth: '8'
Cpp11BracedListStyle: 'true'
DerivePointerAlignment: 'false'
DisableFormat: 'false'
ExperimentalAutoDetectBinPacking: 'false'
FixNamespaceComments: 'true'
IncludeBlocks: Preserve
IndentCaseLabels: 'true'
IndentPPDirectives: None
IndentWidth: '4'
IndentWrappedFunctionNames: 'false'
JavaScriptQuotes: Double
JavaScriptWrapImports: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
NamespaceIndentation: None
PointerAlignment: Left
ReflowComments: 'false'
SortIncludes: 'true'
SortUsingDeclarations: 'true'
SpaceAfterCStyleCast: 'true'
SpaceAfterTemplateKeyword: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: '2'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Cpp11
TabWidth: '4'
UseTab: Never
Run Code Online (Sandbox Code Playgroud)

更新:clang 格式中有一个名为“ConstructorInitializerAllOnOneLineOrOnePerLine”的选项,描述如下:“如果构造函数初始值设定项不适合一行,则将每个初始值设定项放在自己的行上”。但是,它仍然没有做我想要的,因为如果它不适合列限制,它只会将初始化程序移动到一个新行。因此,即使未达到列限制,似乎也无法强制 clang-format 将后续初始化程序放在下一行。如果上述选项变成带有附加值的枚举,即使未达到列限制,也强制将初始化程序放到下一行,那就太好了。

Tho*_*mas 8

我个人使用

BreakConstructorInitializers: BeforeComma
Run Code Online (Sandbox Code Playgroud)

但还有其他选择。见锵格式的样式选项,在部分BreakConstructorInitializers。看起来你的风格会是AfterColon


Nik*_*lai 6

我很确定这是 clang-format 的一个错误/缺点。该问题已在 2015 年解决,但被 clang 格式开发人员拒绝: https //reviews.llvm.org/D14484

对于它的价值,我对 clang-format 做了一个简单的改变,它应该给你你想要的行为:https : //github.com/Nikolai-Hlubek/clang/tree/ConstructorInitializer_AlwaysBreakAfterColon

我向上游提出了推送请求,但我怀疑它是否会被接受。

  • 好多了,我解决了这个问题,并且选项 *PackConstructorInitializers* 解决了这个问题,同时解决了所有极端情况。如果它对您不起作用,此更改是新的,并且仅适用于可能尚未发布的 Clang14。 (2认同)