Why is this an issue?
In some cases, emplace_back
is more efficient and less verbose than push_back
. It is expected to be faster when the
object is constructed into the container instead of being constructed then assigned. This also happens when the pushed object has a different type
from the one held by the container.
This rule supports standard sequence containers: std::vector
, std::list
, std::deque
,
std::forward_list
, std::stack
, std::queue
and std::priority_queue
.
An issue will only be raised when an insertion function on a supported container leads to the construction of a large temporary object that can be
avoided by using the provided emplacement member function.
Noncompliant code example
class Circle { // Large object
std::string s;
int x;
int y;
int radius;
public:
Circle(int x, int y, int radius);
}
void f() {
std::vector<std::pair<int, std::string>> vec1;
std::string s;
vec1.push_back(std::make_pair(21, s)); // Noncompliant
std::vector<std::string> vec2;
vec2.push_back("randomStr"); // Noncompliant, conversion from char const * to string
std::vector<Circle> circles;
circles.push_back(Circle{2, 42, 10}); // Noncompliant
}
Compliant solution
void f() {
std::vector<std::pair<int, std::string>> vec1;
std::string s;
vec1.emplace_back(21, s); // Compliant
std::vector<std::string> vec2;
vec2.emplace_back("randomStr"); // Compliant
std::vector<Circle> circles;
circles.emplace_back(2, 42, 10); // Compliant
}
Exceptions
- When
emplace_back
isn’t exception-safe. When emplacing in a container of smart pointers a raw new expression, the memory will be
leaked if emplace_back
throws an exception.
Resources
- Effective modern C++ item 42: Consider emplacement instead of insertion.