保持函数参数的保守性

2024-03-25

我正在使用整洁的 fmt 库,该库在其版本 8 中会在编译时检查其格式字符串(如果编译器支持相关功能)。

在某些时候,我想编写以下代码:

throw my_exception("error: {}", 123);

可悲的是,天真的实现:

struct my_exception : std::runtime_error {
  template<typename... Args>
  my_exception(Args&&... args)
    : std::runtime_error{fmt::format(std::forward<Args>(args)...)} 
  { }
};

失败,因为这会失去字符串文字参数的“consteval-ness”,这是fmt::format。 目前,我决定以下几点:

template<std::size_t N>
struct literal {
  constexpr literal(const char (&str)[N]) noexcept {
    std::copy_n(str, N, this->str);
  }

  char str[N];
};

template<literal lit>
struct exception : std::runtime_error {
  template<typename... Args>
  exception(Args&&... args)
    : std::runtime_error{fmt::format(lit.str, std::forward<Args>(args)...)}
  {

  }
};

被称为像

throw my_exception<"foo {}">(123);

如何在保持编译时检查的同时恢复正常的函数调用语法?


在 {fmt} 8.0 及更高版本中,您可以使用format_string顾名思义,模板表示格式字符串(https://godbolt.org/z/bqvvMMnjG https://godbolt.org/z/bqvvMMnjG):

struct my_exception : std::runtime_error {
  template <typename... T>
  my_exception(fmt::format_string<T...> fmt, T&&... args)
    : std::runtime_error(fmt::format(fmt, std::forward<T>(args)...)) {}
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

保持函数参数的保守性 的相关文章

随机推荐