Как отформатировать указатели с помощью библиотеки fmt?
Я отвечаю на некоторые вопросы и заглядываю в библиотеку fmt: http://fmtlib.net/
Похоже, что у меня есть нужные мне функции и поддержка %p
(указатель), но при компиляции моего кода, который использует%p, я получаю длинную строку ошибок шаблона (непонятно). Я опубликую их в конце этого.
если я вытащу %p
и соответствующий аргумент указателя, затем он компилируется в VS2017 C++17.
Тем не менее, я в растерянности относительно того, как декодировать ошибки шаблона или получить некоторое представление о том, почему он не принимает %p
аргумент в первую очередь.
Я пытался привести аргумент к (void*)
- та же проблема.
Я попытался использовать синтаксис стиля Python в форматере {}
- та же проблема.
Я разбил биты%p отдельно от остальной части форматирования - та же проблема.
Я вижу, что есть поддержка пользовательских типов - но в этом случае я просто хочу вывести это как необработанное значение указателя. Я мог бы просто пропустить это, ведь насколько ценным может быть адрес указателя? Но, конечно, это означает больше работы во время преобразования из sprintf
в fmt::format
выследить всех%p и "сделать что-нибудь с ними", например, исключить их.
Но документы, кажется, указывают, что%p поддерживается - http://fmtlib.net/latest/syntax.html (примерно 3/4 пути вниз - поиск по "указателю" или "p").
Вот вызывающая функция: (примечание: pAccels
объявлен как const ACCEL *
)
m_hAccel = ::CreateAcceleratorTable(const_cast<LPACCEL>(pAccels), (int)count);
if (!m_hAccel)
{
auto error = GetLastError();
throw CWinAPIErrorException(__FUNCTION__, "CreateAcceleratorTable", fmt::format("%p,%u", pAccels, count), error);
}
Вот диагностическое извержение:
1>c:\users\steve\source\fmt\include\fmt\core.h(1073): error C2825: 'fmt::v5::internal::get_type<Context,Arg>::value_type': must be a class or namespace when followed by '::'
1> with
1> [
1> Context=fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<char>>,char>,
1> Arg=const ACCEL *
1> ]
1>c:\users\steve\source\fmt\include\fmt\core.h(1081): note: see reference to class template instantiation 'fmt::v5::internal::get_type<Context,Arg>' being compiled
1> with
1> [
1> Context=fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<char>>,char>,
1> Arg=const ACCEL *
1> ]
1>c:\users\steve\source\fmt\include\fmt\core.h(1190): note: see reference to function template instantiation 'unsigned __int64 fmt::v5::internal::get_types<Context,const ACCEL*,size_t>(void)' being compiled
1> with
1> [
1> Context=fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<char>>,char>
1> ]
1>c:\users\steve\source\fmt\include\fmt\core.h(1190): note: while compiling class template member function 'unsigned __int64 fmt::v5::format_arg_store<fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<Char>>,Char>,const ACCEL *,size_t>::get_types(void)'
1> with
1> [
1> Char=char
1> ]
1>c:\users\steve\source\fmt\include\fmt\core.h(1478): note: see reference to class template instantiation 'fmt::v5::format_arg_store<fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::buffer<Char>>,Char>,const ACCEL *,size_t>' being compiled
1> with
1> [
1> Char=char
1> ]
1>c:\users\steve\source\tbx\wapi\acceleratortable.cpp(58): note: see reference to function template instantiation 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> fmt::v5::format<char[6],const ACCEL*,size_t,0>(const S (&),const ACCEL *const &,const size_t &)' being compiled
1> with
1> [
1> S=char [6]
1> ]
1>c:\users\steve\source\fmt\include\fmt\core.h(1073): error C2510: 'value_type': left of '::' must be a class/struct/union
1>c:\users\steve\source\fmt\include\fmt\core.h(1073): error C2065: 'type_tag': undeclared identifier
1>c:\users\steve\source\fmt\include\fmt\core.h(1073): error C2131: expression did not evaluate to a constant
1>c:\users\steve\source\fmt\include\fmt\core.h(1073): note: a non-constant (sub-)expression was encountered
1>c:\users\steve\source\fmt\include\fmt\core.h(1197): error C2131: expression did not evaluate to a constant
1>c:\users\steve\source\fmt\include\fmt\core.h(1082): note: failure was caused by non-constant arguments or reference to a non-constant symbol
1>c:\users\steve\source\fmt\include\fmt\core.h(1082): note: see usage of 'value'
1 ответ
Чтобы отформатировать указатель, вы можете либо привести его к void*
:
std::string s = fmt::format("{},{}", static_cast<void*>(pAccels), count);
или завернуть в fmt::ptr
:
std::string s = fmt::format("{},{}", fmt::ptr(pAccels), count);
Рабочий пример для Godbolt: https://godbolt.org/z/sCNbjr
Обратите внимание, что format
использует синтаксис строки формата, подобный Python, а не printf
и возвращает std::string
объект.