diff options
author | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-02-11 18:06:37 +0000 |
---|---|---|
committer | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-02-11 18:06:37 +0000 |
commit | 2f0849fef4883a9cb9e785ae0f90a6d0d00d2959 (patch) | |
tree | b5d34ac9b5ec25a6f87a3b857d7a48c98f4ca46c | |
parent | e1cdce5f761ed0fb04be0aea4d1b9138e9dbc1f7 (diff) | |
download | googletest-2f0849fef4883a9cb9e785ae0f90a6d0d00d2959.tar.gz googletest-2f0849fef4883a9cb9e785ae0f90a6d0d00d2959.tar.bz2 googletest-2f0849fef4883a9cb9e785ae0f90a6d0d00d2959.zip |
Fixes the "ambiguous overload" compiler error when a mock function takes an argument that supports streaming to basic_ostream<C, T>.
-rw-r--r-- | include/gmock/gmock-printers.h | 15 | ||||
-rw-r--r-- | test/gmock-printers_test.cc | 58 |
2 files changed, 71 insertions, 2 deletions
diff --git a/include/gmock/gmock-printers.h b/include/gmock/gmock-printers.h index eae6e52d..759aa347 100644 --- a/include/gmock/gmock-printers.h +++ b/include/gmock/gmock-printers.h @@ -116,8 +116,19 @@ class TypeWithoutFormatter<T, true> { // to simplify the implementation, as much code in 'internal' needs to // use << in STL, which would conflict with our own << were it defined // in 'internal'. -template <typename T> -::std::ostream& operator<<(::std::ostream& os, const T& x) { +// +// Note that this operator<< takes a generic std::basic_ostream<Char, +// CharTraits> type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream<Char, +// CharTraits>, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more +// specific. +template <typename Char, typename CharTraits, typename T> +::std::basic_ostream<Char, CharTraits>& operator<<( + ::std::basic_ostream<Char, CharTraits>& os, const T& x) { TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>:: PrintValue(x, &os); return os; diff --git a/test/gmock-printers_test.cc b/test/gmock-printers_test.cc index 9677491a..6254809b 100644 --- a/test/gmock-printers_test.cc +++ b/test/gmock-printers_test.cc @@ -597,6 +597,64 @@ TEST(PrintWideStringTest, StringInStdNamespace) { } #endif // GTEST_HAS_STD_WSTRING +// Tests printing types that support generic streaming (i.e. streaming +// to std::basic_ostream<Char, CharTraits> for any valid Char and +// CharTraits types). + +// Tests printing a non-template type that supports generic streaming. + +class AllowsGenericStreaming {}; + +template <typename Char, typename CharTraits> +std::basic_ostream<Char, CharTraits>& operator<<( + std::basic_ostream<Char, CharTraits>& os, + const AllowsGenericStreaming& a) { + return os << "AllowsGenericStreaming"; +} + +TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { + AllowsGenericStreaming a; + EXPECT_EQ("AllowsGenericStreaming", Print(a)); +} + +// Tests printing a template type that supports generic streaming. + +template <typename T> +class AllowsGenericStreamingTemplate {}; + +template <typename Char, typename CharTraits, typename T> +std::basic_ostream<Char, CharTraits>& operator<<( + std::basic_ostream<Char, CharTraits>& os, + const AllowsGenericStreamingTemplate<T>& a) { + return os << "AllowsGenericStreamingTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TemplateType) { + AllowsGenericStreamingTemplate<int> a; + EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); +} + +// Tests printing a type that supports generic streaming and can be +// implicitly converted to another printable type. + +template <typename T> +class AllowsGenericStreamingAndImplicitConversionTemplate { + public: + operator bool() const { return false; } +}; + +template <typename Char, typename CharTraits, typename T> +std::basic_ostream<Char, CharTraits>& operator<<( + std::basic_ostream<Char, CharTraits>& os, + const AllowsGenericStreamingAndImplicitConversionTemplate<T>& a) { + return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; +} + +TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { + AllowsGenericStreamingAndImplicitConversionTemplate<int> a; + EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); +} + // Tests printing STL containers. TEST(PrintStlContainerTest, EmptyDeque) { |