2012-03-31 1 views
3

Ich habe eine Schnittstelle mit einer Methode und eine Klasse, die diese Schnittstelle spottet. Die Methode verwendet ein einzelnes Argument. Nur wenn dieses Argument vom Typ std::pair<Something, Something> ist, kann es nicht kompiliert werden. Ich arbeite mit MSVC 2010, also ist es möglich, dass das Problem Compiler- oder STL-spezifische Implementierung ist, es sei denn, das Problem ist wetware-bezogen, das ist meine beste Schätzung. Ich muss etwas Offensichtliches vermissen. Wie Nanosonden.Std :: Paar Argument in Google Mocked Member-Funktion kann nicht kompiliert werden

#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) 
}*/ 

Der tatsächliche Testfall muss nicht unkommentiert sein, damit sich der Fehler manifestiert.

Vorerst arbeite ich dieses Problem um durch die std::pair<> in einem struct Einwickeln, aber das ist suboptimal.

Die Länge der Fehlermeldung ist ziemlich bedauerlich, aber es kann helfen:

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. 

Antwort

1

wie eine Compiler Ausgabe sieht in der Tat; Dies kompiliert OK mit gcc 4.6.

würde eine einfachere Abhilfe MyBorg durch Zeiger auf const passieren sein:

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

oder wenn Sie Boost verwenden glücklich sind, Sie std::pair mit boost::tuple

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

Vielen Dank! Ich überlegte, ob ich einen Fehlerbericht für Google Mock einreichen sollte, aber seit ich ihn erst kürzlich benutze, dachte ich, dass es eher meine Schuld wäre. – irobot

1

ersetzen könnte Wenn Sie ein möchten vollständige Erklärung des Problems gibt es a bug report on this issue with a detailed discussion and investigation. Es ist spezifisch für VS2010 wegen eines Tuple-Konstruktors, der ein Paar direkt nimmt. Die relevante Note ist

versucht, ein Tupel < Paar < T0 zu konstruieren, T1>> von einem Paar < T0, T1> Ergebnisse in einem Aufruf an die erste Konstruktor vorstehend genannt, die ihrerseits versucht T0 zuzuweisen zu paaren < T0, T1>, was den Fehler ergibt.

Die Lösung wäre es, die Tupel vom Paar Konstruktor zu ermöglichen, wenn nur T0 und T1 von dem Paar < T0, T1> gegeben als Argument Spiel T0 und T1 vom Tupel < T0, T1> gebaut.

Es ist ein Fehler in der STL-Implementierung von VS2010 und wurde in der STL-Implementierung von VS2012 behoben.

Ich habe das Problem erfolgreich gelöst, indem ich der Funktionssignatur einen Standardparameter hinzugefügt habe, um einen einzelnen pair< T0, T1 >-Parameter zu vermeiden. Dies führt dazu, dass der problematische Konstruktor vermieden wird.

Verwandte Themen