HippoMocks With weak_ptr

287 views Asked by At

Just stuck with a compilation error of the code trying to mock a method taking std::weak_ptr as argument. HippoMocks has a code to compare it when calling the method With, that doesn't get compiled. I would appreciate any help.

Here is the code:

struct SomeClass {
   SomeClass(){};
   void someMethod(std::weak_ptr<int> d) {}
};

bool operator == (const std::weak_ptr<int> lhs, const std::weak_ptr<int> rhs) {
   return *(lhs.lock()) == *(rhs.lock());
}

BOOST_AUTO_TEST_CASE(test_weak_ptr)
{
   SomeClass obj;
   std::weak_ptr<int> data = std::make_shared<int>(new int(15));

   HippoMocks::MockRepository mocks;

   mocks.ExpectCall(&obj, SomeClass::someMethod).With(data);
}

MS VS 2010 Compiler doesn't like the last line and complains:

d:\hippomocks\hippomocks.h(398): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const std::tr1::weak_ptr<_Ty>' (or there is no acceptable conversion)
      with
      [
          _Ty=int
      ]
      c:\program files (x86)\microsoft sdks\windows\v7.0a\include\guiddef.h(192): could be 'int HippoMocks::operator ==(const HippoMocks::GUID &,const HippoMocks::GUID &)'
      while trying to match the argument list '(const std::tr1::weak_ptr<_Ty>, const std::tr1::weak_ptr<_Ty>)'
      with
      [
          _Ty=int
      ]
      d:\hippomocks\hippomocks.h(397) : while compiling class template member function 'bool HippoMocks::comparer<T>::compare(const std::tr1::weak_ptr<_Ty>,const std::tr1::weak_ptr<_Ty>)'
      with
      [
          T=std::tr1::weak_ptr<int>,
          _Ty=int
      ]
      d:\hippomocks\hippomocks.h(650) : see reference to class template instantiation 'HippoMocks::comparer<T>' being compiled
      with
      [
          T=std::tr1::weak_ptr<int>
      ]
      d:\hippomocks\hippomocks.h(649) : while compiling class template member function 'bool HippoMocks::copy_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP>::operator ==(const HippoMocks::ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &)'
      with
      [
          A=std::tr1::weak_ptr<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,
          CA=const std::tr1::weak_ptr<int> &,
          CB=HippoMocks::NullType,
          CC=HippoMocks::NullType,
          CD=HippoMocks::NullType,
          CE=HippoMocks::NullType,
          CF=HippoMocks::NullType,
          CG=HippoMocks::NullType,
          CH=HippoMocks::NullType,
          CI=HippoMocks::NullType,
          CJ=HippoMocks::NullType,
          CK=HippoMocks::NullType,
          CL=HippoMocks::NullType,
          CM=HippoMocks::NullType,
          CN=HippoMocks::NullType,
          CO=HippoMocks::NullType,
          CP=HippoMocks::NullType
      ]
      d:\hippomocks\hippomocks.h(2985) : see reference to class template instantiation 'HippoMocks::copy_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP>' being compiled
      with
      [
          A=std::tr1::weak_ptr<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,
          CA=const std::tr1::weak_ptr<int> &,
          CB=HippoMocks::NullType,
          CC=HippoMocks::NullType,
          CD=HippoMocks::NullType,
          CE=HippoMocks::NullType,
          CF=HippoMocks::NullType,
          CG=HippoMocks::NullType,
          CH=HippoMocks::NullType,
          CI=HippoMocks::NullType,
          CJ=HippoMocks::NullType,
          CK=HippoMocks::NullType,
          CL=HippoMocks::NullType,
          CM=HippoMocks::NullType,
          CN=HippoMocks::NullType,
          CO=HippoMocks::NullType,
          CP=HippoMocks::NullType
      ]
      d:\unittests\test.cpp(31) : see reference to function template instantiation 'HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P>::With<std::tr1::weak_ptr<_Ty>>(const CA &)' being compiled
      with
      [
          Y=void,
          A=std::tr1::weak_ptr<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,
          _Ty=int,
          CA=std::tr1::weak_ptr<int>
      ]
1

There are 1 answers

0
dascandy On

This is argument-dependent lookup screwing you over. It looks in the namespaces of the arguments only, which is "HippoMocks", "std" and "std". This means it's not even going to consider your global operator==.

Solutions:

  1. Define it in namespace std. Very ugly, but probably where it should've been done if weak_ptr's can be compared.
  2. Define it in namespace HippoMocks. Less ugly, but still pretty ugly.
  3. Instead of making an operator==, make a comparer explicit instantiation. This won't fail at least, but it is much less elegant.
  4. Lobby at the C++ standardization committee to get an operator== on weak_ptr's. Most likely will fail and takes very long.

I suggest #3.