c++使用 fmt::join 格式化无序映射

发布于 2025-01-10 18:31:11 字数 1750 浏览 0 评论 0 原文

我正在尝试使用 fmt 为 std::unordered_map 创建一个 libfmt formatter: :join 但我似乎无法让它工作:

#include <fmt/core.h>
#include <fmt/format.h>
#include <unordered_map>

struct Foo{
  int a;
};

using FooPair = std::pair<std::string, Foo>;
using FooMap = std::unordered_map<std::string, Foo>;


namespace fmt{

template <>
struct formatter<Foo> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const Foo& f, FormatContext& ctx) {
    return format_to(ctx.out(), "\n    {}", f.a);
  }
};

template <>
struct formatter<FooPair> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const FooPair& fp, FormatContext& ctx) {
    return format_to(ctx.out(), "\n  {}{}", fp.first, fp.second);
  }
};


template <>
struct formatter<FooMap> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const FooMap& fm, FormatContext& ctx) {
    return format_to(ctx.out(), "{}", fmt::join(fm.begin(), fm.end(), ""));
  }
};


}




int main(){


FooMap foomap;

fmt::print("Foo Map: {}", foomap);

}

看起来我缺少一个迭代器的格式化程序,但我尝试定义它以及一个迭代器const_iterator 无济于事。这里的最小示例: https://godbolt.org/z/q4615csG6

我确信我只是留下一些愚蠢的东西,我现在看不到它。

I'm trying to create a libfmt formatter for a std::unordered_map<std::string, Foo> using fmt::join but I can't seem to get it to work:

#include <fmt/core.h>
#include <fmt/format.h>
#include <unordered_map>

struct Foo{
  int a;
};

using FooPair = std::pair<std::string, Foo>;
using FooMap = std::unordered_map<std::string, Foo>;


namespace fmt{

template <>
struct formatter<Foo> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const Foo& f, FormatContext& ctx) {
    return format_to(ctx.out(), "\n    {}", f.a);
  }
};

template <>
struct formatter<FooPair> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const FooPair& fp, FormatContext& ctx) {
    return format_to(ctx.out(), "\n  {}{}", fp.first, fp.second);
  }
};


template <>
struct formatter<FooMap> {
  template <typename ParseContext>
  constexpr auto parse(ParseContext& ctx) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const FooMap& fm, FormatContext& ctx) {
    return format_to(ctx.out(), "{}", fmt::join(fm.begin(), fm.end(), ""));
  }
};


}




int main(){


FooMap foomap;

fmt::print("Foo Map: {}", foomap);

}

It looks like I'm missing a formatter for an iterator, but I tried defining that as well as one for a const_iterator to no avail. Minimum example here: https://godbolt.org/z/q4615csG6

I'm sure I'm just leaving something stupid out, I just can't see it at the moment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一江春梦 2025-01-17 18:31:11

这是固定版本:
https://godbolt.org/z/r6dGfzesz

using FooMap = std::unordered_map<std::string, Foo>;
using FooPair = FooMap::value_type;

问题是这样的:使用 FooPair = std ::pair;
注意unordered_map的文档:
std::unordered_map - cppreference.com

value_type std::pair< ;常量键,T>

所以问题是类型不匹配:一对包含键(first)的const,其他则不包含。

所以其他方法来修复它:

using FooPair = std::pair<const std::string, Foo>;

https://godbolt.org/z/9KT9j6h1b

更新2024 年 2 月:对于较新版本的 fmt,还需要进行一项额外更改。 formatter 中的 format 函数也必须是 const

https://godbolt.org/z/s691r16Tz

Here is fixed version:
https://godbolt.org/z/r6dGfzesz

using FooMap = std::unordered_map<std::string, Foo>;
using FooPair = FooMap::value_type;

Problem is this: using FooPair = std::pair<std::string, Foo>;.
Note documentation of unordered_map:
std::unordered_map - cppreference.com

value_type std::pair<const Key, T>

So problems is not matching types: one pair contains const for key (first) other is not.

So other way to fix it:

using FooPair = std::pair<const std::string, Foo>;

https://godbolt.org/z/9KT9j6h1b

Update Feb 2024: With newer versions of fmt there is one additional change that is needed. The format function in formatter<FooPair> must also be const:

https://godbolt.org/z/s691r16Tz

紅太極 2025-01-17 18:31:11

如果不需要格式,可以使用 "fmt::format("{}", fmap)" ,查看 https://github.com/fmtlib/fmt/blob/master/test/ranges-test.cc

if you don't require format, you can use "fmt::format("{}", fmap)" , review the tests from https://github.com/fmtlib/fmt/blob/master/test/ranges-test.cc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文