C++:如何使用 spdlog 打印自定义 class 指针?
C++ : how to use spdlog to print custom class pointer?
我遇到了一个小问题。
我需要使用 spdlog
来登录并且我有自定义的 classes。
因为 spdlog
能够处理 user defined classes,我可以用它来记录我的 classes.
但是,我是我的真实应用程序,我想用我的 class 的指针提供给 spdlog
(因为存在多态性,但这不是重点)。
我的麻烦就在这里。
当我尝试用 class 的 unique_ptr
喂养 spdlog
时,它无法编译。
所以这里是一个 MWE:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <spdlog/spdlog.h> //
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/fmt/ostr.h" // must be included to log object
using namespace std;
struct my_type
{
int i;
template<typename OStream>
friend OStream &operator<<(OStream &os, const my_type &c)
{
return os << "[my_type i=" << c.i << "]";
}
};
template<typename OStream>
OStream &operator<<(OStream &os,const my_type* c)
{
return os << "[my_type i=" << "pointer" << "]";
}
int main() {
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
spdlog::logger logger("log_test", console_sink);
logger.set_level(spdlog::level::trace);
auto pLog =std::make_shared<spdlog::logger>(logger); //register it if you need to access it globally
std::unique_ptr<my_type> ptrA(new my_type{12});
pLog->info("user defined type: {}", ptrA); // of course *ptrA simply works, but in my application I have to give ptrA ...
return 0;
}
我从编译器那里得到错误 gcc
:
spdlog/fmt/bundled/core.h:1566:15: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = my_type; _Dp = std::default_delete<my_type>]’
const auto& arg = arg_mapper<Context>().map(val);
spdlog/fmt/bundled/core.h:1567:3: error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt
static_assert(
spdlog/fmt/bundled/core.h:1184:15: error: use of deleted function ‘fmt::v8::detail::fallback_formatter<T, Char, Enable>::fallback_formatter() [with T = fmt::v8::detail::unformattable; Char = char; Enable = void]’
Formatter f;
^
/spdlog/fmt/bundled/core.h:963:3: note: declared here
fallback_formatter() = delete;
^~~~~~~~~~~~~~~~~~
spdlog/fmt/bundled/core.h:1185:28: error: ‘struct fmt::v8::detail::fallback_formatter<fmt::v8::detail::unformattable, char, void>’ has no member named ‘parse’
parse_ctx.advance_to(f.parse(parse_ctx));
~~^~~~~
spdlog/fmt/bundled/core.h:1186:22: error: ‘struct fmt::v8::detail::fallback_formatter<fmt::v8::detail::unformattable, char, void>’ has no member named ‘format’
ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx));
~~^~~~~~
我猜问题出在 template<typename OStream> OStream &operator<<(OStream &os,const my_type* c)
和 spdlog
或 fmt
之间的交互。所以我试着玩了一下,但我被卡住了。
你有解决这个问题的想法,保持 pLog->info("user defined type: {}", ptrA);
吗?
问题来自库 fmt
自版本 8(由 spdlog
自版本 1.9.0 起使用),不再支持指针。
一个解决方案是使用包装器 class 来存储指针并精确 fmt
应该如何处理它。
我遇到了一个小问题。
我需要使用 spdlog
来登录并且我有自定义的 classes。
因为 spdlog
能够处理 user defined classes,我可以用它来记录我的 classes.
但是,我是我的真实应用程序,我想用我的 class 的指针提供给 spdlog
(因为存在多态性,但这不是重点)。
我的麻烦就在这里。
当我尝试用 class 的 unique_ptr
喂养 spdlog
时,它无法编译。
所以这里是一个 MWE:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <spdlog/spdlog.h> //
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/fmt/ostr.h" // must be included to log object
using namespace std;
struct my_type
{
int i;
template<typename OStream>
friend OStream &operator<<(OStream &os, const my_type &c)
{
return os << "[my_type i=" << c.i << "]";
}
};
template<typename OStream>
OStream &operator<<(OStream &os,const my_type* c)
{
return os << "[my_type i=" << "pointer" << "]";
}
int main() {
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
spdlog::logger logger("log_test", console_sink);
logger.set_level(spdlog::level::trace);
auto pLog =std::make_shared<spdlog::logger>(logger); //register it if you need to access it globally
std::unique_ptr<my_type> ptrA(new my_type{12});
pLog->info("user defined type: {}", ptrA); // of course *ptrA simply works, but in my application I have to give ptrA ...
return 0;
}
我从编译器那里得到错误 gcc
:
spdlog/fmt/bundled/core.h:1566:15: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = my_type; _Dp = std::default_delete<my_type>]’
const auto& arg = arg_mapper<Context>().map(val);
spdlog/fmt/bundled/core.h:1567:3: error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt
static_assert(
spdlog/fmt/bundled/core.h:1184:15: error: use of deleted function ‘fmt::v8::detail::fallback_formatter<T, Char, Enable>::fallback_formatter() [with T = fmt::v8::detail::unformattable; Char = char; Enable = void]’
Formatter f;
^
/spdlog/fmt/bundled/core.h:963:3: note: declared here
fallback_formatter() = delete;
^~~~~~~~~~~~~~~~~~
spdlog/fmt/bundled/core.h:1185:28: error: ‘struct fmt::v8::detail::fallback_formatter<fmt::v8::detail::unformattable, char, void>’ has no member named ‘parse’
parse_ctx.advance_to(f.parse(parse_ctx));
~~^~~~~
spdlog/fmt/bundled/core.h:1186:22: error: ‘struct fmt::v8::detail::fallback_formatter<fmt::v8::detail::unformattable, char, void>’ has no member named ‘format’
ctx.advance_to(f.format(*static_cast<const T*>(arg), ctx));
~~^~~~~~
我猜问题出在 template<typename OStream> OStream &operator<<(OStream &os,const my_type* c)
和 spdlog
或 fmt
之间的交互。所以我试着玩了一下,但我被卡住了。
你有解决这个问题的想法,保持 pLog->info("user defined type: {}", ptrA);
吗?
问题来自库 fmt
自版本 8(由 spdlog
自版本 1.9.0 起使用),不再支持指针。
一个解决方案是使用包装器 class 来存储指针并精确 fmt
应该如何处理它。