无法从 spdlog 中格式化参数
Cannot format argument from within spdlog
我正在尝试使用spdlog
.我将其与我的代码合并,但现在出现以下错误:
....fmtcore.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。最后一个错误行来自这里:
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
是我自己的命名空间中我自己的类。我确实为它提供了一种打印自己的方法:
template<typename OStream>
OStream &operator<<(OStream &os, const Point &p) {
return os << "[" << p.x << ", " << p.y << "]";
}
spdlog使用{fmt}
库来格式化输出文本,这需要包含<fmt/ostream.h>
头文件才能启用类似std::ostream
的支持。
无论使用{fmt}
库的外部实现,还是来自 spdlog 源本身的实现,都有包含正在使用的文件版本的特殊标头<spdlog/fmt/ostr.h>
。
一旦包含,spdlog 应该能够使用您的operator<<
。
或者,您可以创建自定义格式化程序,它也能够解析格式字符串:
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);
}
};
另一个答案总体上是正确的:spdlog
基于{fmt}
库,该库具有内置std::ostream
支持,包括具有重载插入运算符(operator<<
(的用户定义类型的格式设置。
但是从{fmt}
库的版本 9 开始,需要显式地将结构专用化fmt::formatter
用于从ostream_formatter
派生的用户类,如下所示:
#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
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 无法从 spdlog 中格式化参数
- 为什么EclipseCDT代码格式化程序有时会在模板参数中引入空格
- C++fmt库,只使用格式说明符格式化单个参数
- 使用参数的可变大小向量格式化字符串(例如,将参数向量传递给 std::snprintf)
- 可变参数模板必须具有可调用的专用化,非空参数包才能正确格式化
- 如果未设置编译符号,如何排除方法?如何传递可变数量的参数并在函数体中格式化它们
- 在窗口上将格式化的 C 字符串和参数转换为 wstring
- 在回溯跟踪中格式化 GDB 模板参数
- 字符串参数与用于格式化的模板参数
- 为什么 printf 不格式化 unicode 参数?
- 如何在pgsql中格式化数组参数
- QString参数模糊-格式化%1000%2与参数
- c++将格式化字符串作为参数传递给函数
- 格式化不是字符串字面值,也没有格式参数
- C++输出格式化变量参数列表的最佳方法
- 如何确定需要多少参数来实现fprint格式化字符串