Strange behavior of PrintTo/operator<<

1,818 views
Skip to first unread message

An Ky

unread,
Jul 18, 2011, 12:24:00 PM7/18/11
to Google C++ Mocking Framework
Hi there,

having the code snippet below I get the following compiler error:
"error: no match for 'operator<< in '* os << val'" from gtest-
internal.h line 97 which results from the EXPECT_EQ in the test case
at the end. (where val is of type aNamespace::LayoutIndices)

It works if I define operator<< globally. Using PrintTo does not work
at all.

My understanding of the gtest documentation and the C++ NDL rules is
that either method should be found if it is defined in the same
namespace as the typedef. Furthermore PrintTo should be preferred by
gtest.
I'm asking this here and not in the gtest group, because I'm currently
trying to switch from gtest/mockpp to gtest/gmock and in the old
setup, the above code just worked.
I am using tdm-gcc 4.4.1 with gtest/gmock 1.6, migrating from gtest
1.5 and mockpp (dunno which version)

#include <iostream>
#include <gtest/gtest.h>
#include <vector>
using namespace std;

namespace aNamespace {
typedef std::vector<int> LayoutIndices;

std::ostream& operator<<(std::ostream& o, const LayoutIndices& li)
{
o << "no";
return o;
}
}
// void PrintTo(const aNamespace::LayoutIndices& li, std::ostream* o)
// {
// *o << "hello";
// }
//}

int main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv);
int testStatus = RUN_ALL_TESTS();
return testStatus;
}


TEST(Global, equalLayout)
{
aNamespace::LayoutIndices a, b;
EXPECT_EQ(a, b);
}

Vlad Losev

unread,
Jul 21, 2011, 2:12:56 AM7/21/11
to An Ky, Google C++ Mocking Framework
IIRC, when choosing the a function/operator overload using ADL, the compiler looks at the actual types of the parameters. aNamespace::LayoutIndices is only an alias for std::vector<int>. gtest 1.6 defines printing routines for the standard types and the standard STL containers, so std::vector<int> should be output without writing any extra code. Is it not so for you? 

Chandler Carruth

unread,
Jul 21, 2011, 2:21:37 AM7/21/11
to Vlad Losev, An Ky, Google C++ Mocking Framework
On Wed, Jul 20, 2011 at 11:12 PM, Vlad Losev <vl...@losev.com> wrote:
IIRC, when choosing the a function/operator overload using ADL, the compiler looks at the actual types of the parameters. aNamespace::LayoutIndices is only an alias for std::vector<int>.

Yep, I can confirm that's the cause. To be precise, in the final draft of the new C++0x standard, [basic.lookup.argdep] p2 states "Typedef names and using-declarations used to specify the types do not contribute to this set [of associated namespaces]." C++98 followed the same rules here.

Using operators or PrintTo in the global namespace will only work with some non-conforming compilers such as GCC. Clang will almost certainly complain about that as well; it violates the C++ two-phase name lookup rules. We have an explanation of it on the Clang docs here: http://clang.llvm.org/compatibility.html#dep_lookup

An Ky

unread,
Jul 21, 2011, 7:47:03 AM7/21/11
to Google C++ Mocking Framework
Nope, not defining any operator or PrintTo function results in the
same error as above.
Actually it seems that the compiler does not find/use the gmock
default printers because I got the above error comparing stl-iterators
in an ASSERT_EQ() statement.

Vlad Losev

unread,
Jul 21, 2011, 1:29:12 PM7/21/11
to An Ky, Google C++ Mocking Framework
On Thu, Jul 21, 2011 at 4:47 AM, An Ky <ank...@gmail.com> wrote:
Nope, not defining any operator or PrintTo function results in the
same error as above.
Actually it seems that the compiler does not find/use the gmock
default printers because I got the above error comparing stl-iterators
in an ASSERT_EQ() statement.

This is surprising. Google Test includes a catch-all printer which will in almost all circumstances print a hexadecimal dump of the object if neither operator<< nor PrintTo is defined. Make sure you use release 1.6 of gtest/gmock. Earlier releases do not support universal printer for arguments of test assertions.

An Ky

unread,
Jul 22, 2011, 8:50:10 AM7/22/11
to Google C++ Mocking Framework
Thanks vor pointing this out... I accidentally used gmock 1.5 :/
Reply all
Reply to author
Forward
0 new messages