Invoke, Functors and ReturnRef

1,345 views
Skip to first unread message

Oskar Sundbom

unread,
Jun 13, 2016, 12:38:44 PM6/13/16
to Google C++ Testing Framework
Hi!

I was implementing a mock factory function that would generate new objects, themselves mocks, with an implementation that would have all objects return a reference to the same object:

MyMock::MyMock(Thing thing) {
  // ...
  ON_CALL(*this, SomeFunction(_))
    .WillByDefault(Invoke([thing] {
      auto* object = new MockObject;
      // GetThing returns a const Thing&.
      EXPECT_CALL(*object, GetThing()).WillRepeatedly(ReturnRef(thing));
      return object;
    })); 
}

I expected the first lamba, capturing thing here by-value would stick around somewhere in the mock class, get invoked whenever SomeFunction was called, and let the mocked object it generated return a reference to it.
I was, however, unable to get it to work. Whenever I referenced values in the Thing returned by GetThing, they'd all be wildly wrong.
I've traced the reason down to InvokeHelper::Invoke taking its function parameter by-value, copying my (lambda) functor on invocation of SomeFunction, and making GetThing return a reference to the thing inside the temporary functor.

see:

I've only seen lambda-friendly template functions like this take their function argument by rvalue-reference (i.e. Function&& in this case) and an informal change and rebuild of that call fixed the issue. (I'm of course not keeping it like that).
Is the copying of the functor during invocation a mistake or intended behavior?

I've worked around it for now, by putting the Thing somewhere else, but it seems to me like this should work.

Best regards,
Oskar
Reply all
Reply to author
Forward
0 new messages