Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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.