我曾经能够将 Eigen3 数组/矩阵传递给 spdlog,它内部使用 libfmt。从 libfmt 9.0.0 开始,这些类型不再由 libfmt 格式化,无需进一步的代码。
fmt 通过专门化支持自定义类型fmt::formatter<T>
对于类型;fmt9 文档 https://fmt.dev/9.0.0/api.html#std-ostream-support进一步解释说,这种专业化源于ostream_formatter
将利用现有的operator<<
,本征类可以方便地提供。
Eigen 使用CRTP继承 https://eigen.tuxfamily.org/dox/TopicClassHierarchy.html我会专门为所有人Eigen::DenseBase<T>
像这样的类型:
#include<fmt/ostream.h>
#include<eigen3/Eigen/Core>
#include<iostream>
template <typename T> struct fmt::formatter<T,std::enable_if_t<std::is_base_of_v<Eigen::DenseBase<T>,T>>>: ostream_formatter {};
int main(){
Eigen::Array3f a(1,2,3);
std::cout<<fmt::format("{}",a)<<std::endl;
}
自从我发帖以来,很明显这并不顺利:
In file included from /usr/include/fmt/format.h:48,
from /usr/include/fmt/ostream.h:18,
from /tmp/aa.cpp:1:
/usr/include/fmt/core.h: In instantiation of ‘constexpr fmt::v9::detail::value<Context> fmt::v9::detail::make_value(T&&) [with Context = fmt::v9::basic_format_context<fmt::v9::appender, char>; T = Eigen::Array<float, 3, 1>&]’:
/usr/include/fmt/core.h:1771:29: required from ‘constexpr fmt::v9::detail::value<Context> fmt::v9::detail::make_arg(T&&) [with bool IS_PACKED = true; Context = fmt::v9::basic_format_context<fmt::v9::appender, char>; fmt::v9::detail::type <anonymous> = fmt::v9::detail::type::custom_type; T = Eigen::Array<float, 3, 1>&; typename std::enable_if<IS_PACKED, int>::type <anonymous> = 0]’
/usr/include/fmt/core.h:1895:77: required from ‘constexpr fmt::v9::format_arg_store<Context, Args>::format_arg_store(T&& ...) [with T = {Eigen::Array<float, 3, 1, 0, 3, 1>&}; Context = fmt::v9::basic_format_context<fmt::v9::appender, char>; Args = {Eigen::Array<float, 3, 1, 0, 3, 1>}]’
/usr/include/fmt/core.h:1912:31: required from ‘constexpr fmt::v9::format_arg_store<Context, typename std::remove_cv<typename std::remove_reference<Args>::type>::type ...> fmt::v9::make_format_args(Args&& ...) [with Context = fmt::v9::basic_format_context<fmt::v9::appender, char>; Args = {Eigen::Array<float, 3, 1, 0, 3, 1>&}]’
/usr/include/fmt/core.h:3184:44: required from ‘std::string fmt::v9::format(fmt::v9::format_string<T ...>, T&& ...) [with T = {Eigen::Array<float, 3, 1, 0, 3, 1>&}; std::string = std::__cxx11::basic_string<char>; fmt::v9::format_string<T ...> = fmt::v9::basic_format_string<char, Eigen::Array<float, 3, 1, 0, 3, 1>&>]’
/tmp/aa.cpp:7:24: required from here
/usr/include/fmt/core.h:1751:7: 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
1751 | formattable,
| ^~~~~~~~~~~
/usr/include/fmt/core.h:1751:7: note: ‘formattable’ evaluates to false
我可以获得一些如何正确执行此操作的解释吗?我想既了解这里 C++ 的情况,又想有一个基于此的可行解决方案。谢谢!