diff --git a/include/fmt/format.h b/include/fmt/format.h index 7c2a19b4084de..d8ac67f5b6ce9 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3990,13 +3990,23 @@ FMT_FORMAT_AS(long, detail::long_type); FMT_FORMAT_AS(unsigned long, detail::ulong_type); FMT_FORMAT_AS(Char*, const Char*); FMT_FORMAT_AS(std::nullptr_t, const void*); -FMT_FORMAT_AS(detail::std_string_view, basic_string_view); FMT_FORMAT_AS(void*, const void*); template class formatter, Char> : public formatter, Char> {}; +// Fixes issue #4036 +template +struct formatter, Char> + : public formatter, Char> { + auto format(const detail::std_string_view& value, + format_context& ctx) const -> decltype(ctx.out()) { + using base = formatter, Char>; + return base::format(value, ctx); + } +}; + template struct formatter : formatter, Char> {}; diff --git a/test/format-test.cc b/test/format-test.cc index a9ef19fc19c81..5477ecd257610 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1650,6 +1650,20 @@ TEST(format_test, format_explicitly_convertible_to_std_string_view) { EXPECT_EQ("'foo'", fmt::format("{}", explicitly_convertible_to_std_string_view())); } + +struct convertible_to_std_string_view { + operator std::string_view() const noexcept { return "Hi there"; } +}; +FMT_BEGIN_NAMESPACE +template <> +class formatter + : public formatter {}; +FMT_END_NAMESPACE + +TEST(format_test, format_implicitly_convertible_and_inherits_string_view) { + static_assert(fmt::is_formattable{}); + EXPECT_EQ("Hi there", fmt::format("{}", convertible_to_std_string_view{})); +} #endif class Answer {};