C++ – Doing work in vector’s push back

cexceptions

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?

Best 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.