diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index cdb39047..94f18834 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -53,8 +53,7 @@ struct test_stream : std::basic_ostream { void operator<<(null); }; -// Checks if T has an overloaded operator<< which is a free function (not a -// member of std::ostream). +// Checks if T has a user-defined operator<< (e.g. not a member of std::ostream). template class is_streamable { private: @@ -69,7 +68,9 @@ class is_streamable { typedef decltype(test(0)) result; public: - static const bool value = result::value; + // std::string operator<< is not considered user-defined because we handle strings + // specially. + static const bool value = result::value && !std::is_same::value; }; // Disable conversion to int if T has an overloaded operator<< which is a free diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 85fea764..88c202d3 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -163,3 +163,7 @@ TEST(OStreamTest, Join) { int v[3] = {1, 2, 3}; EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); } + +TEST(OStreamTest, ConstexprString) { + EXPECT_EQ("42", format(fmt("{}"), std::string("42"))); +}