dascandy / hippomocks

GNU Lesser General Public License v2.1
195 stars 66 forks source link

NotPrintable can be ambiguous with other operator<< overloads #23

Open macong-earth opened 10 years ago

macong-earth commented 10 years ago

I've a test case for a function with functional argument

#include "hippomocks.h"
#include <functional>

using namespace HippoMocks;

struct A
{
    virtual void f(std::function<void (int)> arg);
};

int main(void)
{
    MockRepository mock;
    A* aptr = mock.Mock<A>();

    mock.ExpectCall(aptr, A::f);

    aptr->f([](int i) {});

    return 0;
}

It worked fine with g++ 4.8.0 g++ -std=c++11 main.cpp // works fine

but printed errors while I compiled it with MS 2010

the error is

C:\Users\Cong\Project\test\test>cl main.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
c:\users\cong\project\test\test\hippomocks.h(466) : error C2593: 'operator <<' i
s ambiguous
        c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\ostream(2
06): could be 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Trai
ts>::operator <<(std::_Bool)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>
        ]
        c:\users\cong\project\test\test\hippomocks.h(441): or       'std::ostrea
m &HippoMocks::operator <<(std::ostream &,const HippoMocks::NotPrintable &)'
        while trying to match the argument list '(std::ostream, std::tr1::functi
on<_Fty>)'
        with
        [
            _Fty=void (int)
        ]
        c:\users\cong\project\test\test\hippomocks.h(463) : while compiling clas
s template member function 'void HippoMocks::printArg<T>::print(std::ostream &,T
,bool)'
        with
        [
            T=std::tr1::function<void (int)>
        ]
        c:\users\cong\project\test\test\hippomocks.h(614) : see reference to cla
ss template instantiation 'HippoMocks::printArg<T>' being compiled
        with
        [
            T=std::tr1::function<void (int)>
        ]
...................
dascandy commented 10 years ago

MSVC can't figure out how to print the argument. The intent of NotPrintable was to catch these cases (and it looks like GCC is letting it do that just fine) but it also looks like MSVC ships with a default print function for booleans that can also be used. I'm not entirely sure what the best fix would be... let me check what the language standard says about this case. The NotPrintable conversion should not be rated as high as the boolean one, since it was constructed specifically to be selected least likely.

rossmacgregor commented 10 years ago

You know what? We are seeing the same error with g++-4.8. We are using boost and -std=c++03 and the following version of hippomocks from the old git repo:

2010-12-14 [dascandy] Added no-exceptions support, added LGPLv2 header to make it clear once & for all. Fixed up some ifdef checks to check for the right thing. Made auto-expect changeable for the entire use of hippomocks instead of per-test. 37c825483c

#include <cstdio> // hippomocks needs printf defined
#include <boost/function.hpp>
#include "hippomocks.h"

using namespace HippoMocks;

struct A
{
    virtual void f(boost::function<void (int)> arg);
};

int main(void)
{
    MockRepository mock;
    A* aptr = mock.Mock<A>();

    mock.ExpectCall(aptr, A::f);

    return 0;
}

It's generating the following output:

g++ boost_function.cpp
In file included from boost_function.cpp:3:0:
hippomocks.h: In instantiation of ‘static void HippoMocks::printArg<T>::print(std::ostream&, T, bool) [with T = boost::function<void(int)>; std::ostream = std::basic_ostream<char>]’:
hippomocks.h:492:35:   required from ‘void HippoMocks::ref_tuple<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>::printTo(std::ostream&) const [with A = boost::function<void(int)>; B = HippoMocks::NullType; C = HippoMocks::NullType; D = HippoMocks::NullType; E = HippoMocks::NullType; F = HippoMocks::NullType; G = HippoMocks::NullType; H = HippoMocks::NullType; I = HippoMocks::NullType; J = HippoMocks::NullType; K = HippoMocks::NullType; L = HippoMocks::NullType; M = HippoMocks::NullType; N = HippoMocks::NullType; O = HippoMocks::NullType; P = HippoMocks::NullType; std::ostream = std::basic_ostream<char>]’
boost_function.cpp:20:1:   required from here
hippomocks.h:349:6: error: ambiguous overload for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘boost::function<void(int)>’)
   os << arg;
      ^
hippomocks.h:349:6: note: candidates are:
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from /usr/local/include/boost/assert.hpp:84,
                 from /usr/local/include/boost/function/function_base.hpp:20,
                 from /usr/local/include/boost/function/detail/prologue.hpp:17,
                 from /usr/local/include/boost/function.hpp:24,
                 from boost_function.cpp:2:
/usr/include/c++/4.8/ostream:174:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
       operator<<(bool __n)
       ^
In file included from boost_function.cpp:3:0:
hippomocks.h:330:22: note: std::ostream& HippoMocks::operator<<(std::ostream&, const HippoMocks::NotPrintable&)
 inline std::ostream &operator<<(std::ostream &os, NotPrintable const&)
                      ^
make: *** [default] Error 1

Glad to see some hippomock activity, I'm a long time hippomock user and promoter.

rzr commented 8 years ago

Thius problem is still present on current master branch w/ gcc-4.8

dascandy commented 7 years ago

I know this problem is still present right now, but I'm not sure how to fix it. Any ideas?