Google Mocked成员函数中的std :: pair参数无法编译

时间:2012-03-31 14:29:19

标签: c++ visual-c++ compiler-errors googlemock std-pair

我有一个方法接口和一个模拟该接口的类。该方法采用单个参数。只有当该参数的类型为std::pair<Something, Something>时才会无法编译。我正在使用MSVC 2010,因此问题可能是编译器或STL实现特定的,除非当然问题是与wetware相关,这是我最好的猜测。我一定错过了一些明显的东西。像纳米探针一样。

#include <gmock/gmock.h>

class BorgInterface
{
public:
    typedef std::pair<int, long> MyBorg; // <--- MyBorg is problematic!
    //typedef long MyBorg; // ..but this MyBorg complies
    virtual void Assimilate( MyBorg borg_in_training ) = 0;
};

class MockBorg
    : public BorgInterface
{
public:
    MOCK_METHOD1( Assimilate, void( BorgInterface::MyBorg borg_in_training ));
};

/*TEST( MyBorgTestCase, BorgInterfaceTest )
{
    using ::testing::_;

    MockBorg funny_borg;
    EXPECT_CALL( funny_borg, Assimilate( _ ));
    // ...etc. (irrelevant)
}*/

实际的测试用例不必取消注释,以便错误显示出来。

目前,我通过将std::pair<>包裹在struct中解决此问题,但这不是最佳的。

错误消息的长度是相当不幸的,但它可能会有所帮助:

1>Build started 3/31/2012 4:02:43 PM.
1>ClCompile:
1>  test_pair_parameter_mock.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tuple(127):
   error C2664: 'std::pair<_Ty1,_Ty2>::pair(const std::pair<_Ty1,_Ty2> &)'
       : cannot convert parameter 1 from 'int' to 'const std::pair<_Ty1,_Ty2> &'
1>          with
1>          [
1>              _Ty1=int,
1>              _Ty2=long
1>          ]
1>          Reason: cannot convert from 'int' to 'const std::pair<_Ty1,_Ty2>'
1>          with
1>          [
1>              _Ty1=int,
1>              _Ty2=long
1>          ]
1>          No constructor could take the source type,
             or constructor overload resolution was ambiguous
1>          c:\...\microsoft visual studio 10.0\vc\include\tuple(404)
               : see reference to function template instantiation
                'std::tr1::_Cons_node<_Car,_Cdr>::_Cons_node<
                  _Ty1&,_Ty2&,std::tr1::_Nil&,std::tr1::_Nil&,
                  std::tr1::_Nil&,
                  ...............
                  std::tr1::_Nil&,
                  std::tr1::_Nil&>(_Farg0,...,_Farg9)' being compiled
1>          with
1>          [
1>              _Car=BorgInterface::MyBorg,
1>              _Cdr=std::tr1::_Tuple_type<
                  std::tr1::_Nil,
                  ..............
                  std::tr1::_Nil,
                  std::tr1::_Nil>::_Type,
1>              _Ty1=int,
1>              _Ty2=long,
1>              _Farg0=int &,
1>              _Farg1=long &,
1>              _Farg2=std::tr1::_Nil &,
1>              .......................
1>              _Farg9=std::tr1::_Nil &
1>          ]
1>          d:\...\gmock\include\gmock\gmock-generated-function-mockers.h(97) :
                see reference to function template instantiation
                 'std::tr1::tuple<_Arg0>::tuple<int,long>(
                   std::pair<_Ty1,_Ty2> &)' being compiled
1>          with
1>          [
1>              _Arg0=BorgInterface::MyBorg,
1>              _Ty1=int,
1>              _Ty2=long
1>          ]
1>          d:\...\gmock\include\gmock\gmock-generated-function-mockers.h(92) :
               while compiling class template member function
                'void testing::internal::FunctionMocker<Function>::Invoke(A1)'
1>          with
1>          [
1>              Function=void (BorgInterface::MyBorg),
1>              A1=BorgInterface::MyBorg
1>          ]
1>          d:\..\myapp\src\tests\unit_tests\test_pair_parameter_mock.cpp(17) :
               see reference to class template instantiation
                'testing::internal::FunctionMocker<Function>' being compiled
1>          with
1>          [
1>              Function=void (BorgInterface::MyBorg)
1>          ]
1>
1>Build FAILED.

2 个答案:

答案 0 :(得分:1)

看起来确实是编译器问题;这可以使用gcc 4.6编译好。

更简单的解决方法是将MyBorg通过指针传递给const:

    virtual void Assimilate( const MyBorg *borg_in_training ) = 0;

或者如果您乐意使用Boost,可以将std::pair替换为boost::tuple

    typedef boost::tuple<int, long> MyBorg;

答案 1 :(得分:1)

如果您想要问题的完整说明,请a bug report on this issue with a detailed discussion and investigation。它特定于VS2010,因为元组构造函数直接使用了一对。相关说明是

  

尝试构建一个元组&lt;对&lt; T0,T1> &GT;从一对&lt; T0,T1>结果   在调用上面提到的第一个构造函数时,它反过来尝试   将T0指定为配对&lt; T0,T1&gt;,产生错误。

     

解决方案是仅从对构造函数启用元组   如果该对中的T0和T1 < T0,T1>作为参数匹配T0和T1   来自元组&lt; T0,T1>正在建设中。

这是VS2010 STL实现中的一个缺陷,并已在VS2012的STL实现中得到修复。

我通过在函数签名中添加默认参数来成功解决此问题,以避免使用单个pair< T0, T1 >参数。这导致了有问题的构造函数被避免。