Я просмотрел несколько статей о пользовательских средствах форматирования для библиотеки форматирования C++20, но многие из них кажутся слегка неверными или не могут скомпилироваться в моей цепочке инструментов. Ниже приведена моя текущая реализация специального средства форматирования, которое обрабатывает нестроковые диапазоны. Я ищу подтверждение того, правильно ли это и есть ли какие-либо улучшения. Обратите внимание: цель примера — применить любой спецификатор формата к каждому элементу диапазона.
#include
#include
#include
template concept is_stringlike =
std::same_as ||
std::same_as ||
std::same_as ||
std::same_as;
template concept is_non_stringlike_range =
std::ranges::range &&
!is_stringlike;
template
struct std::formatter : std::formatter {
auto format(R const& range, auto & ctx) const {
auto out = ctx.out();
out = std::format_to(out, "[");
auto sep = "";
for (auto const& v : range) {
out = std::format_to(out, "{}", sep);
ctx.advance_to(out);
out = std::formatter::format(v, ctx);
sep = ", ";
}
return std::format_to(out, "]");
}
};
int main() {
std::println("{:>2}", std::views::iota(0, 11));
return 0;
}
Вот некоторые конкретные предположения, которые отличаются от многих примеров, которые я видел. Это правильно?
Метод format должен быть шаблонизирован на основе типа контекста формата, а не использовать std::format_context, как многие онлайн-примеры подсказывают это.
Метод format должен быть константным.
При использовании format_to выходной итератор необходимо обновлять вручную. (). В большинстве примеров предполагается использование std::back_insert_iterator, но, насколько я могу судить, стандарт не требует этого даже для std::format_context.
Я просмотрел несколько статей о пользовательских средствах форматирования для библиотеки форматирования C++20, но многие из них кажутся слегка неверными или не могут скомпилироваться в моей цепочке инструментов. Ниже приведена моя текущая реализация специального средства форматирования, которое обрабатывает нестроковые диапазоны. Я ищу подтверждение того, правильно ли это и есть ли какие-либо улучшения. Обратите внимание: цель примера — применить любой спецификатор формата к каждому элементу диапазона. [code]#include #include #include
auto format(R const& range, auto & ctx) const { auto out = ctx.out(); out = std::format_to(out, "["); auto sep = "";
for (auto const& v : range) { out = std::format_to(out, "{}", sep);
ctx.advance_to(out); out = std::formatter::format(v, ctx);
sep = ", "; }
return std::format_to(out, "]"); } };
int main() { std::println("{:>2}", std::views::iota(0, 11)); return 0; } [/code] Вот некоторые конкретные предположения, которые отличаются от многих примеров, которые я видел. Это правильно? [list] [*]Метод format должен быть шаблонизирован на основе типа контекста формата, а не использовать std::format_context, как многие онлайн-примеры подсказывают это. [*]Метод format должен быть константным. [*]При использовании format_to выходной итератор необходимо обновлять вручную. (). В большинстве примеров предполагается использование std::back_insert_iterator, но, насколько я могу судить, стандарт не требует этого даже для std::format_context. [/list]