用于非常量参数的自定义类 fmt::formatter

问题描述 投票:0回答:1

我有课:

class MyClass{
   public:
   std::string _cachedString;
   std::string_view get_string(){
      _cachedString = "abc";
      return _cachedString;
   }
};

template<>
class fmt::formatter<MyClass>{
    public:
    template<typename ParseContext>
    constexpr auto parse(ParseContext& ctx){return ctx.begin();}

    template <typename FormatContext>
    constexpr auto format( MyClass& t, FormatContext& ctx){
        return format_to(ctx.out(), "({})", t.get_string());
    }
};

我查了一下,发现您需要将

const MyClass& t
作为参数传递给格式函数。但就我而言,由于我正在修改对象,所以我不能。当我编译此代码时,出现此错误:

 undefined reference to `fmt::v8::detail::value<fmt::v8::basic_format_context<fmt::v8::appender, char> >::value(fmt::v8::detail::unformattable_const)'

当我删除在 MyClass 对象上调用 fmt::format 的行时,它就会消失。如何纠正这个问题?

c++ polymorphism overloading derived-class fmt
1个回答
0
投票

您应该将

format
函数本身设置为 const:

template<>
struct fmt::formatter<MyClass> {
  constexpr auto parse(format_parse_context& ctx){return ctx.begin();}

  template <typename FormatContext>
  constexpr auto format(MyClass& t, FormatContext& ctx) const {
    return format_to(ctx.out(), "({})", t.get_string());
  }
};

否则你的示例可以在最新版本的 {fmt} 中运行(godbolt):

int main() {
  MyClass c;
  fmt::print("{}", c);
}

正如 @super 在评论中正确指出的那样,更好的解决方案是使

_cachedString
可变并且
get_string
const:

class MyClass {
 public:
  mutable std::string _cachedString;

  std::string_view get_string() const {
    _cachedString = "abc";
    return _cachedString;
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.