有没有办法抑制用户定义的类的 fmt 范围格式化程序?

如何解决有没有办法抑制用户定义的类的 fmt 范围格式化程序?

我有一个简单的类,它有一个 tostring() 方法

class MyClass {
  public:

    std::string tostring() const;

    static iterator begin();
    static iterator end();
};

虽然我现在正在使用 fmt 库,但是这段代码是从没有的代码中移植过来的,所以许多遗留类都实现了 tostring() 方法,而且我有一个模板可以为任何具有该方法的类。它运行良好。

然而,这个特殊的类也有开始/结束功能。但是,它们是静态的(此类类似于枚举,您可以遍历所有可能的值),并且与格式无关。

一切都很好,直到我需要为一些不同的代码包含 fmt/ranges.h。问题是有一个范围格式化程序可以看到开始/结束函数并希望将类格式化为范围。现在,如果我尝试格式化类,我会得到格式化程序的模棱两可的实例(一个用于我要使用的模板,一个用于范围格式化程序)。

有没有办法让范围格式化程序忽略这个类?

一个完整的例子是:

#include <type_traits>
#include <utility>
#include <string>
#include <vector>
#include <fmt/format.h>
// #include <fmt/ranges.h>


// Create formatter for any class that has a tostring() method

template <typename T>
struct has_tostring_member {
private:
  template <typename U>
  static std::true_type  test( decltype(&U::tostring) );
  template <typename U>
  static std::false_type test(...);
public:
  using result = decltype(test<T>(0) );
  static constexpr bool  value = result::value;
};

template <typename T,typename Char>
struct  fmt::formatter<T,Char,std::enable_if_t<has_tostring_member<T>::value > >
  : formatter<basic_string_view<Char>,Char> {
  template <typename FormatContext>
  auto
  format( const T& e,FormatContext& ctx )
  {
    return formatter<string_view>::format( e.tostring(),ctx );
  }
};


class MyClass
{
public:
  explicit MyClass(int i) : value(i) {}

  std::string tostring() const { return std::to_string(value); }

  static auto begin() { return std::begin(static_data); }
  static auto end() { return std::end(static_data); }

private:
  int  value;
  static const std::vector<std::string> static_data;
};


 const std::vector<std::string> MyClass::static_data{ "a","b","c" };

int main(void) {
  MyClass c{10};

  fmt::print("c is {}\n",c);

  return 0;
}

如果我对 MyClass 有完整的 fmt::formatter 专业化,那么没有歧义,但是如果我像在示例中那样使用部分专业化,则取消注释“#include " 会导致模版实例化不明确。

解决方法

以下是选项(您已经发现):

  1. 不要包含 fmt/ranges.h
  2. 提供 formatter 的完整专业化。

请注意,如果您为所有具有 tostring 的类型实现了通用格式化程序,则只需一行 (https://godbolt.org/z/cW3WzaP6f) 即可执行 (2):

template <> struct fmt::formatter<MyClass> : tostring_formatter<MyClass> {};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?