формат clang версии 9.0.1, примененный к коду C ++.
Сочетание AlwaysBreakAfterReturnType
и AfterFunction
дает мне странные результаты. Взаимодействие с различными параметрами кажется довольно тонким, поэтому мне интересно, что мне нужно сделать, чтобы получить желаемый результат (который будет).
Во-первых, форматируемый код.
int foo(int, double);
int bar(int, double) { return 42; }
template <typename T, typename U> XY<T, U> xy1(X, Y y) { return XY<T, U>{}; }
template <typename T, typename U> XY<T, U> xy2(X, Y) { return XY<T, U>{}; }
Обратите внимание, что единственное различие между функциями xy1
и xy2
заключается в том, что xy1
предоставляет имя для этого последнего параметра, а xy2
не называет ни одного из его параметров.
Далее содержимое минимального файла .clang-формата.
---
BasedOnStyle: LLVM
AlwaysBreakAfterReturnType: TopLevelDefinitions
Запуск clang-формата отформатирует исходный код следующим образом.
int foo(int, double);
int
bar(int, double) {
return 42;
}
template <typename T, typename U>
XY<T, U>
xy1(X, Y y) {
return XY<T, U>{};
}
template <typename T, typename U>
XY<T, U>
xy2(X, Y) {
return XY<T, U>{};
}
Однако мне нужна открывающая фигурная скобка для функции в отдельной строке, не упакованной справа от функции.
Из документов я должен установить BraceWrapping/AfterFunction
в значение true, что приведет к следующему файлу в формате .clang.
---
BasedOnStyle: LLVM
AlwaysBreakAfterReturnType: TopLevelDefinitions
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
Это приводит к следующему результату форматирования.
int foo(int, double);
int
bar(int, double)
{
return 42;
}
template <typename T, typename U>
XY<T, U>
xy1(X, Y y)
{
return XY<T, U>{};
}
template <typename T, typename U> XY<T, U> xy2(X, Y) { return XY<T, U>{}; }
Это то, что я ожидаю, за исключением форматирования функции xy2
, которая не соответствует ожиданиям, и даже не близко к форматированию для xy1
, и это именно то, что я ожидал.
Если я go чуть дальше и форсирую разрыв для шаблона, то я получаю этот файл в формате .clang ...
---
BasedOnStyle: LLVM
AlwaysBreakAfterReturnType: TopLevelDefinitions
AlwaysBreakTemplateDeclarations: Yes
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
, который производит этот форматированный вывод.
int foo(int, double);
int
bar(int, double)
{
return 42;
}
template <typename T, typename U>
XY<T, U>
xy1(X, Y y)
{
return XY<T, U>{};
}
template <typename T, typename U>
XY<T, U> xy2(X, Y)
{
return XY<T, U>{};
}
Это ближе, но форматирование для xy2
полностью игнорирует запрос на разрыв после возвращаемого типа.
Тонкое взаимодействие между различными параметрами сбивает с толку, и я не смог придумать способ получить то, что я хочу, в основном для функций, у которых нет явных аргументов для форматирования так же, как те, которые есть явные аргументы.
Опять же, обратите внимание на тонкую разницу между xy1
и xy2
. xy1
имеет по крайней мере один именованный параметр, в то время как xy2
не имеет именованных параметров - но не имеет bar
.
Обратите внимание также, что обычная функция bar
не имеет именованных параметров и все же он отформатирован правильно, в то время как шаблон функции xy2
все еще не отформатирован должным образом.
Какая комбинация опций magi c приведет к тому, что xy2
будет отформатирован так же, как xy1
и bar
?
Спасибо.