Say I have a method which creates a non-trivially constructable object which is RVO'd back to the caller. For example
MyComplexClass value = deserialize();
deserialize
throws an exception on failure, so I want to do something like
EXPECT_NO_THROW(MyComplexClass value = deserialize());
but of course, value goes out of scope (since the macro introduces a try/catch block). And also
MyComplexClass value;
EXPECT_NO_THROW(value = deserialize());
does not work since there is no default constructor (for example it is = delete
).
Any ideas on this? I could do something like
template<typename TResult>
TResult return_assert_no_throw(std::function<TResult()> expression)
{
try
{
return expression();
}
catch (const std::exception & ex)
{
ASSERT_TRUE(false);
}
}
but this seems a little hacky, and we lose information on the exception
Judging by the desired syntax of value = deserialize()
more generally, whatever type value is it should be copy-able and/or move-able for that to work. Therefore if you can create a dummy value/null valued instance of the class you are still good to go. You can simply initialise value
to a particular dummy/canary instance, and then verify afterwards that the value changed properly. You may have/want to std::swap()
.