Форматирование типа путем возврата к указателю с помощью библиотеки fmt

#c #c 14 #fmt

#c #c 14 #fmt

Вопрос:

Я пытаюсь использовать

 fmt::format("Expected : '{}' vs. '{}'", getDataOrPointer(rA), getDataOrPointer(rB));
 

где getDataOrPointer должен быть возвращен void указатель (который всегда можно отформатировать) или значение по умолчанию, когда существует средство форматирования:

 //! Return the type if a `fmt::formatter` exists.
template<typename T,
         typename std::enable_if_t<hasFormatter<std::decay<T>, char>>* = 0>
decltype(auto) getDataOrPointer(const Tamp; rData)
{
    return rData;
}

//! Return a void-Pointer if no `fmt::formatter` exists.
template<typename T,
         typename std::enable_if_t<!hasFormatter<std::decay<T>, char>>* = 0>
const void* getDataOrPointer(const Tamp; rData)
{
    return static_cast<const void*>(amp;rData);
}
 

Я не знаю, как написать: hasFormatter<T,char> проверить, может ли он быть отформатирован fmt библиотекой или нет?. Я хочу, чтобы этот резервный вариант был только локально, а не всегда.

Ответ №1:

Вы можете использовать fmt::has_formatter , заключая в кавычки https://github.com/fmtlib/fmt/issues/1369:

has_formatter<T, Context> сообщает вам, что тип T имеет formatter специализацию для Context (контекст в основном определяет типы символов и выходных итераторов), и его можно использовать с SFINAE. Пример: https://godbolt.org/z/pCD14x . Основное предостережение заключается в том, что типы с неявным преобразованием могут быть форматируемыми, но не иметь formatter специализации.

Комментарии:

1. См. github.com/fmtlib/fmt/issues/1369#event-4248590915