У меня есть typedef
над unordered_map
из Eigen
векторов и перегруженный оператор ostream <<
:
namespace wolf{
typedef unordered_map<std::string, Eigen::VectorXd> VectorComposite;
std::ostream& operator <<(std::ostream &_os, const VectorComposite &_x)
{
for (const auto &pair_key_vec : _x)
{
const auto &key = pair_key_vec.first;
const auto &vec = pair_key_vec.second;
_os << "\n block(" << key << ") = \n" << vec;
}
return _os;
}
} // namespace wolf
Я могу заставить этот оператор работать для стандартных std::cout
,
VectorComposite x;
x.emplace("P", Vector2d(1,1));
x.emplace("O", Vector3d(2,2,2));
cout << "x = " << x << endl;
выдает хороший результат, как и ожидалось:
x =
block(O) =
2
2
2
block(P) =
1
1
Однако, когда я пытаюсь использовать spdlog
методы ведения журнала, такие как debug()
, я получаю ошибки компиляции. Поскольку реализация spdlog представляет собой шаблон variadi c, мне трудно отладить проблему. Я стараюсь указывать c:
Вот мой вызов spdlog, через собственный определенный макрос
WOLF_DEBUG("x = " , x);
Я должен сказать, что этот макрос работал отлично в течение многих лет, и что это первый раз, когда он терпит неудачу, особенно с использованием упомянутых operator<<
и VectorComposite
typedef.
Вот макрос расширения:
#define WOLF_DEBUG(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).debug(__VA_ARGS__);
это длинная строка , включая несвязанные вопросы, такие как синглтон. Важной частью является определение __VA_ARGS__
, переданного функции debug()
.
Вот наша реализация debug(__VA_ARGS__)
в строке выше, которая теперь вызывает по очереди spdlog::debug()
template<typename... Args>
void Logger::debug(Args&&... args) const
{
console_->debug(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
}
Чтобы иметь дело с переменным числом аргументов, переменная repeated_brace
- это способ передать определенное количество фигурных скобок, т.е.
static const auto repeated_brace = std::make_tuple("{}",
"{}{}",
"{}{}{}",
"{}{}{}{}",
"{}{}{}{}{}",
"{}{}{}{}{}{}",
"{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}"); // up to 25 args. Should be fine
, где в нашем случае я думаю, что одна или две повторяющиеся фигурные скобки debug(...)
.
Наконец, вот определение spdlog::logger::debug()
метода в spdlog/details/logger_impl.h
строке 130
template <typename Arg1, typename... Args>
inline void spdlog::logger::debug(const char* fmt, const Arg1 &arg1, const Args&... args)
{
log(level::debug, fmt, arg1, args...);
}
Я прошу прощения за длинное объяснение, но с вариади c Я полностью запутался в том, какие аргументы наконец передаются в функцию spdlog::logger::debug()
, поэтому я не знаю, как на самом деле отлаживать это. Я надеюсь, что вы, ребята, сможете это понять.
Мне кажется, что ошибка может быть связана с тем, что мы используем typedef в качестве объекта для печати. У нас есть аналог operator<<
для класса MatrixComposite
, который похож на VectorComposite
, который отлично работает как с std::cout
, так и с spdlog::...::debug()
.
Компилятор жалуется на следующий стек сообщений об ошибках :
/usr/local/include/spdlog/fmt/bundled/ostream.h:90:12: error: invalid operands to binary expression ('std::basic_ostream<char>' and 'const std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >')
output << value;
~~~~~~ ^ ~~~~~
/usr/local/include/spdlog/fmt/bundled/format.h:1401:9: note: in instantiation of function template specialization 'fmt::format<char, fmt::ArgFormatter<char>, std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
format(*static_cast<Formatter*>(formatter),
^
/usr/local/include/spdlog/fmt/bundled/format.h:1503:26: note: in instantiation of function template specialization 'fmt::internal::MakeValue<fmt::BasicFormatter<char, fmt::ArgFormatter<char> > >::format_custom_arg<std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
custom.format = &format_custom_arg<T>;
^
/usr/local/include/spdlog/fmt/bundled/format.h:2496:20: note: in instantiation of function template specialization 'fmt::internal::MakeValue<fmt::BasicFormatter<char, fmt::ArgFormatter<char> > >::MakeValue<std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
Value result = MakeValue<Formatter>(value);
^
/usr/local/include/spdlog/fmt/bundled/format.h:2922:5: note: in instantiation of function template specialization 'fmt::internal::ArgArray<2, true>::make<fmt::BasicFormatter<char, fmt::ArgFormatter<char> >, std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
FMT_VARIADIC_VOID(write, BasicCStringRef<Char>)
^
/usr/local/include/spdlog/fmt/bundled/format.h:2565:26: note: expanded from macro 'FMT_VARIADIC_VOID'
ArgArray::template make<fmt::BasicFormatter<Char> >(args)...}; \
^
/usr/local/include/spdlog/details/logger_impl.h:69:21: note: in instantiation of function template specialization 'fmt::BasicWriter<char>::write<char [5], std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
log_msg.raw.write(fmt, args...);
^
/usr/local/include/spdlog/details/logger_impl.h:133:5: note: in instantiation of function template specialization 'spdlog::logger::log<char [5], std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
log(level::debug, fmt, arg1, args...);
^
/Users/jsola/dev/wolf_lib/core/include/core/utils/logging.h:179:13: note: in instantiation of function template specialization 'spdlog::logger::debug<char [5], std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > >' requested here
console_->debug(std::get<sizeof...(args)-1>(repeated_brace), std::forward<Args>(args)...);
^
/Users/jsola/dev/wolf_lib/core/test/gtest_state_composite.cpp:331:5: note: in instantiation of function template specialization 'wolf::internal::do_not_enter_where_the_wolf_lives::Logger::debug<char const (&)[5], std::__1::unordered_map<std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > &>' requested here
WOLF_DEBUG("x = " , x);
^
/Users/jsola/dev/wolf_lib/core/include/core/utils/logging.h:315:94: note: expanded from macro 'WOLF_DEBUG'
#define WOLF_DEBUG(...) wolf::internal::WolfLogger::get(__INTERNAL_WOLF_MAIN_LOGGER_NAME_).debug(__VA_ARGS__);