Fix reference_wrapper ambiguity with format_as (#4434)

This commit is contained in:
Jeremy Rifkin
2025-05-10 13:15:45 -05:00
committed by GitHub
parent 55a8f6a4be
commit 4999416e5c
2 changed files with 52 additions and 1 deletions

View File

@@ -678,9 +678,28 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
}
};
namespace detail {
template <typename T, typename Enable = void>
struct has_format_as : std::false_type {};
template <typename T>
struct has_format_as<T, void_t<decltype(format_as(std::declval<const T&>()))>>
: std::true_type {};
template <typename T, typename Enable = void>
struct has_format_as_member : std::false_type {};
template <typename T>
struct has_format_as_member<
T, void_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>>
: std::true_type {};
} // namespace detail
// Guard against format_as because reference_wrappers are implicitly convertible
// to T&
template <typename T, typename Char>
struct formatter<std::reference_wrapper<T>, Char,
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value &&
!detail::has_format_as<T>::value &&
!detail::has_format_as_member<T>::value>>
: formatter<remove_cvref_t<T>, Char> {
template <typename FormatContext>
auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const