diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index b6408921..938d1176 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -46,9 +46,9 @@ template class formatbuf : public std::basic_streambuf { template struct test_stream : std::basic_ostream { private: - struct null; // Hide all operator<< from std::basic_ostream. - void operator<<(null); + void_t<> operator<<(null<>); + void_t<> operator<<(const Char*); }; // Checks if T has a user-defined operator<< (e.g. not a member of @@ -56,9 +56,9 @@ template struct test_stream : std::basic_ostream { template class is_streamable { private: template - static decltype((void)(std::declval&>() - << std::declval()), - std::true_type()) + static bool_constant&>() + << std::declval()), + void_t<>>::value> test(int); template static std::false_type test(...); diff --git a/test/ostream-test.cc b/test/ostream-test.cc index d1e72b5a..6c2bc412 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -242,3 +242,15 @@ TEST(FormatTest, UDL) { EXPECT_EQ("{}"_format("test"), "test"); } #endif + +template +struct convertible { + T value; + explicit convertible(const T& val) : value(val) {} + operator T() const { return value; } +}; + +TEST(OStreamTest, ConvertibleToCString) { + EXPECT_EQ("x", fmt::format("{}", convertible('x'))); + EXPECT_EQ("foo", fmt::format("{}", convertible("foo"))); +}