首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法从spdlog中格式化参数

无法从spdlog中格式化参数
EN

Stack Overflow用户
提问于 2020-06-11 08:28:46
回答 2查看 3.9K关注 0票数 3

我正在尝试使用spdlog。我将它与我的代码结合在一起,但现在我得到了以下错误:

代码语言:javascript
运行
复制
....fmt\core.h(1016): error C2338: Cannot format argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#formatting-user-defined-types
  ....fmt/core.h(1013): note: while compiling class template member function 'int fmt::v6::internal::arg_mapper<Context>::map(...)'
          with
          [
              Context=context
          ]
  ....fmt/core.h(1213): note: see reference to function template instantiation 'int fmt::v6::internal::arg_mapper<Context>::map(...)' being compiled
          with
          [
              Context=context
          ]
  ....fmt/core.h(1027): note: see reference to class template instantiation 'fmt::v6::internal::arg_mapper<Context>' being compiled
          with
          [
              Context=context
          ]
  ....fmt/core.h(1198): note: see reference to alias template instantiation 'fmt::v6::internal::mapped_type_constant<int,context>' being compiled
  ....fmt/core.h(1342): note: see reference to function template instantiation 'unsigned __int64 fmt::v6::internal::encode_types<Context,int,>(void)' being compiled
          with
          [
              Context=context
          ]
  ....fmt/format.h(3375): note: see reference to class template instantiation 'fmt::v6::format_arg_store<context,int>' being compiled
  ....spdlog/details/fmt_helper.h(49): note: see reference to function template instantiation 'std::back_insert_iterator<fmt::v6::internal::buffer<char>> fmt::v6::format_to<char[6],int&,250,char>(fmt::v6::basic_memory_buffer<char,250,std::allocator<char>> &,const S (&),int &)' being compiled
          with
          [
              S=char [6]
          ]

..。这是错误信息的结束。它从来没有到达我的代码,所以我不知道去哪里看。有什么可以解释的吗?

spdlog是1.6.1版本。最后一个错误行来自这里:

代码语言:javascript
运行
复制
inline void pad2(int n, memory_buf_t &dest)
{
    if (n >= 0 && n < 100) // 0-99
    {
        dest.push_back(static_cast<char>('0' + n / 10));
        dest.push_back(static_cast<char>('0' + n % 10));
    }
    else // unlikely, but just in case, let fmt deal with it
    {
        fmt::format_to(dest, "{:02}", n);  // <--- HERE
    }
}

在我看来并没有什么特别的错误。

更新:在尝试和错误注释掉所有spdlog调用之后,我将范围缩小到以下几个方面:

spdlog::info("Foo{}", Point{1, 2});

其中Point是我自己命名空间中的类。我确实提供了一种打印自己的方法:

代码语言:javascript
运行
复制
template<typename OStream>
OStream &operator<<(OStream &os, const Point &p) {
    return os << "[" << p.x << ", " << p.y << "]";
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-11 14:22:55

spdlog使用{fmt}库格式化输出文本,这需要<fmt/ostream.h>头文件将包括在内来启用std::ostream-like支持。

不管是使用{fmt}库的外部实现,还是使用spdlog源本身的实现,都有一个特殊的头<spdlog/fmt/ostr.h>,它包含正在使用的文件版本。

包含之后,spdlog应该能够使用您的operator<<

或者,您可以创建一个自定义格式化程序,它还能够解析格式化字符串:

代码语言:javascript
运行
复制
template <>
struct fmt::formatter<Point> {
    constexpr auto parse(format_parse_context& ctx) {
        return ctx.end();
    }

    template <typename Context>
    auto format(const Point& p, Context& ctx) {
        return format_to(ctx.out(), "[{}, {}]", p.x, p.y);
    }
};
票数 4
EN

Stack Overflow用户

发布于 2022-08-21 18:00:39

另一个答案是完全正确的:spdlog是基于{fmt}库的,它具有内置std::ostream支持,包括对具有重载插入运算符(operator<<)的用户定义类型的格式化。

但是,从{fmt}库的版本9开始,需要为从ostream_formatter派生的用户类显式地专门化fmt::formatter结构,如下所示:

代码语言:javascript
运行
复制
#include <spdlog/fmt/ostr.h>

#if FMT_VERSION >= 90000
    template <> struct fmt::formatter<Point> : ostream_formatter{};
#endif

请参阅:https://fmt.dev/dev/api.html#ostream-api

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62320177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档