在 C++20 中实现自定义 std::formatter 的正确方法是什么?

问题描述 投票:0回答:1

我看过几篇关于 C++20 格式化库的自定义格式化程序的文章,但许多文章似乎有些微妙的错误或无法在我的工具链上编译。下面是一个我认为正确的示例,后面是 3 个具体问题。

#include <print>

struct CustomType {
    int a;
};

template<>
struct std::formatter<CustomType> : std::formatter<int> {

    // use format specifiers for int
    using std::formatter<int>::parse;

    auto format(CustomType const& x, auto & ctx) const {
        auto out = ctx.out();
        out = std::format_to(out, "[");

        ctx.advance_to(out);
        out = std::formatter<int>::format(x.a, ctx);

        return std::format_to(out, "]");
    }
};

int main() {
    std::println("{:>2}", CustomType{1});
    return 0;
}

这些说法正确吗?

  1. format
    方法应该在格式上下文类型上进行模板化,而不是使用
    std::format_context
    ,正如许多在线示例所建议的那样。
  2. format
    方法应该是const限定的。
  3. 使用
    format_to()
    时需要手动更新输出迭代器。大多数示例都忽略了这一点,并且似乎假设了
    std::back_insert_iterator
    ,但据我所知,即使对于
    std::format_context
    ,标准也没有强制要求。
c++ c++20 stdformat
1个回答
0
投票

格式方法应该在格式上下文类型上模板化,而不是使用 std::format_context,正如许多在线示例所建议的那样。

是的。

格式化方法应该是const限定的。

是的。

使用format_to()时需要手动更新输出迭代器。大多数示例都忽略了这一点,并且似乎假设有一个 std::back_insert_iterator,但据我所知,即使对于 std::format_context,标准也没有强制要求。

是的。虽然该库倾向于对所有 char 类型使用相同的迭代器类型,但这并不是您可以做的唯一事情 - 并且如果

format
曾经使用具有迭代器类型(其位置很重要)的上下文进行实例化 -就像,
char*
- 那么如果您不这样做
advance_to
,您的下一个格式将覆盖您的第一个格式。

因此,可能不太容易出现以下错误:

ctx.advance_to(std::format_to(ctx.out(), "["));
ctx.advance_to(std::formatter<int>::format(x.a, ctx));
return std::format_to(ctx.out(), "]");

尽管这无疑更乏味。如果对这类事情有更好的库支持那就太好了,但我不确定那会是什么样子。

© www.soinside.com 2019 - 2024. All rights reserved.