I often use the following syntax: std::vector<foo> vec; vec.push_back( someClass
ID: 655515 • Letter: I
Question
I often use the following syntax:
std::vector<foo> vec;
vec.push_back( someClass.getFoo(...).modifyAndReturn() );
Considered about exception safety, I quote the standard on vector's push back behavior (23.3.7.5):
If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation there are no effects. If an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.
Is it a good practice to use complicated push backs?
Are there any perils exception wise?
Explanation / Answer
Whether using such complicated expressions in a push back (or any other function call) is debatable and it depends on two factors: 1. your local coding conventions, and 2. the comfort level of you and your team with reading such expressions
Regarding exception safety, there is no difference between these three snippets:
std::vector<foo> vec;
vec.push_back( someClass.getFoo(...).modifyAndReturn(...) );
std::vector<foo> vec;
auto temp = someClass.getFoo(...).modifyAndReturn(...);
vec.push_back( temp );
std::vector<foo> vec;
auto temp = someClass.getFoo(...);
auto temp2 = temp.modifyAndReturn(...);
vec.push_back( temp2 );
The exception safety of std::vector<>::push_back does not really enter into the picture, because if getFoo or modifyAndReturn would throw an exception, push_back won't even be called. In C++, arguments to a function are always evaluated before the function gets called.