3

我有一个方法接口和一个模拟该接口的类。该方法采用单个参数。只有当该参数是类型时std::pair<Something, Something>,它才会编译失败。我正在使用 MSVC 2010,所以问题可能是编译器或 STL 实现特定的,当然,除非问题与湿件相关,这是我的最佳猜测。我一定遗漏了一些明显的东西。就像纳米探针一样。

#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<>目前,我通过将a包装来解决这个问题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.
4

2 回答 2

1

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

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

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

或者如果您乐于使用 Boost,您可以替换std::pairboost::tuple

    typedef boost::tuple<int, long> MyBorg;
于 2012-03-31T18:02:26.417 回答
1

如果您想要对该问题的完整解释,请参阅有关此问题的错误报告,其中包含详细的讨论和调查。它特定于 VS2010,因为元组构造函数直接采用一对。相关说明是

尝试从 pair< T0, T1 > 构造元组 < pair < T0, T1 > > 会导致调用上述第一个构造函数,该构造函数又尝试将 T0 分配给 pair< T0, T1 >,从而产生错误。

解决方案是仅当作为参数给出的对<T0,T1>中的T0和T1与正在构造的元组<T0,T1>中的T0和T1匹配时,才启用对构造函数中的元组。

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

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

于 2014-03-04T23:14:10.163 回答