c++ - 用户定义类型的 std::format ?

标签 c++ c++20 fmt

在 C++20 中 - 如何使用户定义的类型与 std::format 兼容?

例如,假设我有一个名为 Point 的类型。 :

struct Point {
    int x;
    int y;
};

与其 operator<<定义:
inline std::ostream&
operator<<(std::ostream& o, Point pt)
{ return o << "[" << pt.x << << ", " << pt.y << "]"; }

那么下面的程序会输出Hello [3, 4]! ?
int main() {
   Point pt{3,4};
   std::cout << std::format("Hello {}!\n", pt);
}

如果是 - 为什么以及如何?

如果没有 - 我必须在 Point 的定义中添加什么让它发挥作用?

最佳答案

std::format不支持 operator<< ,您需要提供 formatter 而是针对您的类型 ( Point ) 进行特化。最简单的方法是重用现有的格式化程序之一,例如std::formatter<std::string> :

template <>
struct std::formatter<Point> : std::formatter<std::string> {
  auto format(Point p, format_context& ctx) {
    return formatter<string>::format(
      std::format("[{}, {}]", p.x, p.y), ctx);
  }
};

这将为您提供 std::string 支持的所有格式规范盒子外面。这是格式化 Point 的示例用 '~' 填充中心对齐到 10 个字符:
auto s = std::format("{:~^10}", Point{1, 2});
// s == "~~[1, 2]~~"

使用 iostreams 实现这一点非常重要。

关于c++ - 用户定义类型的 std::format ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59909102/

相关文章:

c++ - spdlog 错误 : "don' t know how to format the type, 包括 fmt/ostream.h(如果它提供了应使用的运算符 <<)”

C++ 代码优化

c++ - 谷歌基准代码设置

c++ - 皮肤 WinAPI 控件

c++ - 将值从 flex 传递给 bison

c++ - 为什么在引用类型上使用新的放置会给我带来段错误,即使使用 std::launder 也是如此?

c++ - 为什么 "The one ranges proposal"包含每个 View 的两个名称是否有特定原因?

c++ - 为什么 fmt::format 不接受字符串作为参数?

c++ - C++ fmt::print 与 fmt::format_to 命名的技术背景?

Visual Studio 中的 C++20 支持