2013-03-01 12 views
6

Obecnie nie udaje mi się kpić z interfejsu, który zwraca wartość unique_ptr. Na przykład, biorąc pod uwagęHippoMocks - kpiąc z funkcji zwracającej unique_ptr

struct IFoo {  
    virtual std::unique_ptr<IFoo> foo = 0; 
}; 


int main() 
{ 
    MockRepository mocks; 
    auto foo = mocks.Mock<IFoo>(); 
    mocks.OnCall(foo, IFoo::foo) 
     .Return(std::unique_ptr<IFoo>()); 
} 

to zawiedzie skompilować ponieważ realizacja Return sprawia kopię unique_ptr

Call &Return(Y obj) { retVal = new ReturnValueWrapper<Y>(obj); return *this; } 

i oczekiwanie próbuje zwrócić unique_ptr

template <typename Z> 
Z MockRepository::DoExpectation(base_mock *mock, std::pair<int, int> funcno, const base_tuple &tuple) 
{ 
    ... 
    return ((ReturnValueWrapper<Z> *)call->retVal)->rv; 
} 

mam wypróbowany Do, zgodnie z sugestią for a similar problem with returned references.

Próbowałem również napisać własny ValueWrapper<T>, który generuje unique_ptr, ale gdzieś wartość jest zawsze kopiowana. W tej chwili zabrakło mi pomysłów.

+1

Wygląda na to, że HippoMocks nie jest jeszcze gotowy na typy ruchu typu C++ 11. Może mógłbyś napisać specjalizację dla 'ReturnValueWrapper >' która nie * nie * kopiuje wewnętrznie? –

+0

Czy wypróbowałeś późniejsze wersje hippomocks, które mają wersję C++ 0x? –

+0

@Arne Miałem mniej więcej próbowałem czegoś takiego. Najwyraźniej zrobiłem coś złego na początku. Po kolejnym przejściu znalazłem rozwiązanie, które działało. Dodam go do [repozytorium github] (https://github.com/dascandy/hippomocks) później. – Thomas

Odpowiedz

2

Jednym z rozwiązań tego problemu jest do tworzenia interfejsu wyprowadza się dodatkową, która zwraca wartość powrotną jako tymczasowy

template <class T> 
class TypedReturnValueHolder : public ReturnValueHolder { 
public: 
    virtual T rv() = 0; 
}; 

i ich modyfikacji oryginalnej ReturnValueHolder

template <class T> 
class ReturnValueWrapper : public ReturnValueHolder { 
public: 
typename no_cref<T>::type rv; 
ReturnValueWrapper(T rv) : rv(rv) {} 
}; 

dziedziczyć i implementuj wyprowadzony interfejs.

template <class T> 
class ReturnValueWrapper : public TypedReturnValueHolder<T> { 
    typename no_cref<T>::type prv; 
public: 
    ReturnValueWrapper(T rv) : prv(rv) {} 
    virtual T rv() { return prv; }; 
}; 

Kiedy to zostało zrobione, powrót z DoExpectation można zapisać jako

 if (call->retVal) 
      return ((TypedReturnValueHolder<Z> *)call->retVal)->rv(); 

przykładzie z pytaniem kiedy przepisany do korzystania Do

mocks.OnCall(foo, IFoo::foo) 
    .Do([](){ return std::unique_ptr<IFoo>(); }); 

następnie kompiluje i działa jako spodziewany.

Powiązane problemy