One solution to the problem is to create a derived interface with an additional method that returns the return value as a temporary
template <class T>
class TypedReturnValueHolder : public ReturnValueHolder {
public:
virtual T rv() = 0;
};
and them modifying the original ReturnValueHolder
template <class T>
class ReturnValueWrapper : public ReturnValueHolder {
public:
typename no_cref<T>::type rv;
ReturnValueWrapper(T rv) : rv(rv) {}
};
to inherit from and implement the derived interface.
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; };
};
Once that has been done, the return from DoExpectation
can be written as
if (call->retVal)
return ((TypedReturnValueHolder<Z> *)call->retVal)->rv();
The example from the question when rewritten to use Do
mocks.OnCall( foo, IFoo::foo )
.Do( [](){ return std::unique_ptr<IFoo>(); } );
then compiles and runs as expected.