专门格式化指向类的指针

发布于 2025-01-18 12:22:42 字数 1424 浏览 0 评论 0原文

我需要为阶级层次结构提供格式 - 魔法,通常这些东西是通过指针传递的。此示例此处当前在master上使用:

#include <type_traits>
#include <sstream>
#include <fmt/format.h>
#include <fmt/ostream.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, std::remove_const_t<std::remove_pointer_t<T>>>::value, char>> : fmt::formatter<std::string> {
  template <typename FormatCtx>
  auto format(const A* a, FormatCtx& ctx) {
    return fmt::formatter<std::string>::format(a->name(), ctx);
  }
};

template<class... T>
[[noreturn]] void err(fmt::format_string<T...> s, T&&... args) {
    throw std::logic_error(fmt::format(s, std::forward<T>(args)...));
}

int main() {
    A* a = new A();
    B* b = new B();
    const A* x = new A();
    const B* y = new B();
    fmt::print("{}, {}, {}, {}\n", a, b, x, y);
    std::ostringstream oss;
    fmt::print(oss, "{}\n", a);
    err("{}, {}, {}, {}\n", a, b, x, y);
}

但是,当我要使用最新版本8.1.1时,我得到了:

error: static assertion failed: Formatting of non-void pointers is disallowed.

现在我的问题是:这里的计划是什么?我可以在以后的FMT版本中执行此操作,还是更多是偶然的?

I need to provide format-magic to a class hierarchy and usually those things are passed around via pointer. This example here works currently on master:

#include <type_traits>
#include <sstream>
#include <fmt/format.h>
#include <fmt/ostream.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, std::remove_const_t<std::remove_pointer_t<T>>>::value, char>> : fmt::formatter<std::string> {
  template <typename FormatCtx>
  auto format(const A* a, FormatCtx& ctx) {
    return fmt::formatter<std::string>::format(a->name(), ctx);
  }
};

template<class... T>
[[noreturn]] void err(fmt::format_string<T...> s, T&&... args) {
    throw std::logic_error(fmt::format(s, std::forward<T>(args)...));
}

int main() {
    A* a = new A();
    B* b = new B();
    const A* x = new A();
    const B* y = new B();
    fmt::print("{}, {}, {}, {}\n", a, b, x, y);
    std::ostringstream oss;
    fmt::print(oss, "{}\n", a);
    err("{}, {}, {}, {}\n", a, b, x, y);
}

However, when I'm going to the latest release 8.1.1, I'm getting:

error: static assertion failed: Formatting of non-void pointers is disallowed.

Now my question is: What's the plan here? Can I do this in future versions of fmt or is this more of an accident?

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

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

发布评论

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

评论(1

最初的梦 2025-01-25 12:22:42

这绝对是一种回归。支持类的层次结构可以按照 https://fmt 中的记录来完成.dev/latest/api.html#formatting-user-defined-types 使用引用而不是指针:

#include <type_traits>
#include <fmt/format.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
    fmt::formatter<std::string> {
  template <typename FormatCtx>
  auto format(const A& a, FormatCtx& ctx) {
    return fmt::formatter<std::string>::format(a.name(), ctx);
  }
};

int main() {
  B b;
  A& a = b;
  fmt::print("{}", a); // prints "B"
}

This is definitely a regression. Supporting a hierarchy of classes can be done as documented in https://fmt.dev/latest/api.html#formatting-user-defined-types using references instead of pointers:

#include <type_traits>
#include <fmt/format.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
    fmt::formatter<std::string> {
  template <typename FormatCtx>
  auto format(const A& a, FormatCtx& ctx) {
    return fmt::formatter<std::string>::format(a.name(), ctx);
  }
};

int main() {
  B b;
  A& a = b;
  fmt::print("{}", a); // prints "B"
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文