Аргумент std :: pair в функции-члене Google Mocked не компилируется - PullRequest
3 голосов
/ 31 марта 2012

У меня есть интерфейс с одним методом и класс, имитирующий этот интерфейс. Метод принимает один аргумент. Только когда этот аргумент имеет тип 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<> в 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 ]

1 голос
/ 05 марта 2014

Если вы хотите получить полное объяснение проблемы, есть отчет об ошибке по этой проблеме с подробным обсуждением и исследованием .Он специфичен для VS2010 из-за конструктора кортежей, который напрямую принимает пару.Соответствующее примечание:

попытка создать кортеж > из пары приводит к вызову первого упомянутого выше конструктора, который, в свою очередь, пытается назначитьT0 для пары , что приводит к ошибке.

Решение состоит в том, чтобы включить кортеж из конструктора пары, только если T0 и T1 из пары , заданной в качестве аргумента, соответствуют T0 и T1из создаваемого кортежа .

Это дефект в реализации STL VS2010 и был исправлен в реализации STL VS2012.

Я успешно обошел проблему, добавивпараметр по умолчанию для сигнатуры функции, чтобы избежать использования одного pair< T0, T1 > параметра.Это приводит к тому, что проблемного конструктора избегают.

1 голос
/ 31 марта 2012

Похоже, проблема компилятора;он компилируется нормально, используя 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;
...