Можно ли проверить, что форматтер определён?

Есть некий кастомный тип. Я хочу проверить в коде, что если для него определён std::formatter, то перевести в строку с помощью него, а если нет - то напечатать хардкод строку. Можно ли так сделать (желательно ещё в компайл тайме)?

struct A{};

if (there_is_formatter()) {
  std::print("{}", A{});
} else {
  std::print("no formatter");
}

Ответы (2 шт):

Автор решения: isnullxbh

Первичный шаблон std::formatter имеет следующее определение:

template<typename _Tp, typename _CharT = char>
struct formatter
{
    formatter() = delete;
    // code
};

Это значит, что как только Вы попытаетесь вызвать конструктор по умолчанию std::formatter<X>, для которого не определена специализация, Вы получите ошибку компиляции.

Соответственно, можно отталкиваться от этого:

if constexpr (std::is_default_constructible_v<std::formatter<X>>) { ... }

Только учтите, чтобы у Вас это [проверка] сработало в compile-time - должен работать вывод типов, соответственно, в регулярной функции такое не напишешь :)

Пример

→ Ссылка
Автор решения: HolyBlackCat

В C++23 и новее так if constexpr (std::formattable<A>).

В C++20 так: if constexpr (std::default_initializable<std::formatter<X>>) (это в целом эквивалентно std::is_default_constructible_v из соседнего ответа).

→ Ссылка