如何使用 clang-format 格式化地图初始化?

How to format a map initialization with clang-format?

我正试图在一个相当大的 C++ 项目中引入 clang-format。除了少数情况外,一切都很好。最烦人的是地图初始化的格式化结果。我试图通过谷歌搜索找到关于 clang 格式的标志或任何解决方案,但我没有找到任何东西。有问题的代码片段:

// before formatting

const std::map<std::type_index, void *> functionMap{
  {typeid(DummyClassAAAAA), (bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &operator== },
  {typeid(DummyClassBBBB), (bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) &operator== },
  {typeid(DummyClassCCC), (bool (*)(const DummyClassCCC &, const DummyClassCCC &)) &operator== },
  {typeid(DummyClassDDDDDDDDD), (bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) &operator== },
  {typeid(DummyClassEEEEEEE), (bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) &operator== },
  {typeid(DummyClassFFFFFFFFFF), (bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) &operator== }
};

// after formatting

const auto functionMap = std::map<std::type_index, void *>{{typeid(DummyClassAAAAA),
  (bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &operator== },
  {typeid(DummyClassBBBB), (bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) &operator== },
    {typeid(DummyClassCCC), (bool (*)(const DummyClassCCC &, const DummyClassCCC &)) &operator== },
      {typeid(DummyClassDDDDDDDDD), (bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) &operator== },
        {typeid(DummyClassEEEEEEE), (bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) &operator== },
          {typeid(DummyClassFFFFFFFFFF),
            (bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) &operator== } };

我的 .clang-format 文件:

UseTab: Never
IndentWidth: 2
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false
ColumnLimit: 120
ContinuationIndentWidth: 2
ConstructorInitializerIndentWidth: 2
PointerAlignment: Right
DerivePointerAlignment: false
AlignAfterOpenBracket: DontAlign
AllowShortBlocksOnASingleLine: false
SpaceAfterTemplateKeyword: false
AlwaysBreakTemplateDeclarations: Yes
AlignTrailingComments: true
IndentCaseLabels: true
BreakBeforeBinaryOperators: NonAssignment
AllowAllParametersOfDeclarationOnNextLine: false

我在 Windows 上使用 clang-format version 9.0.0 (tags/RELEASE_900/final)

此处唯一的要求是初始化列表中的每一对都应另起一行,但在同一列中。我不想为任何代码片段关闭 clang-format,所以我真的很想通过配置 clang-format 来产生正确的输出来解决它。

任何想法,如何解决这个问题?也许如果没有办法实现这一点,那么有人可以提供任何证据吗?

编辑 - 解决方案

添加额外的大括号后,结果如下所示:

const std::map<std::type_index, void *> functionMap{
  {typeid(DummyClassAAAAA), ((bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) & operator==)},
  {typeid(DummyClassBBBB), ((bool (*)(const DummyClassBBBB &, const DummyClassBBBB &)) & operator==)},
  {typeid(DummyClassCCC), ((bool (*)(const DummyClassCCC &, const DummyClassCCC &)) & operator==)},
  {typeid(DummyClassDDDDDDDDD), ((bool (*)(const DummyClassDDDDDDDDD &, const DummyClassDDDDDDDDD &)) & operator==)},
  {typeid(DummyClassEEEEEEE), ((bool (*)(const DummyClassEEEEEEE &, const DummyClassEEEEEEE &)) & operator==)},
  {typeid(DummyClassFFFFFFFFFF), ((bool (*)(const DummyClassFFFFFFFFFF &, const DummyClassFFFFFFFFFF &)) & operator==)},
};

我不能告诉你为什么 clang-format 在这种情况下以这种方式进行格式化,以及它是否应该被视为一个错误。

但在这种情况下,大括号可以帮助解决格式问题,因为它改变了 AST,因此改变了应用的规则,以及用作对齐参考的内容。

在值部分周围添加大括号将更正地图项的对齐方式:

{typeid(DummyClassAAAAA),
       ((bool (*)(const DummyClassAAAAA &, const DummyClassAAAAA &)) &
        operator==)}

根据您希望在完整列表中保持什么样的整体对齐方式,您需要在最后一项之后添加一个逗号,例如强制 }; 换行。