Sometimes, 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 and 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.
The rule raises an issue when an insertion function on a supported container leads to constructing a large temporary object that can be avoided
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
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.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
The rule does not raise an issue when emplace_back is not exception-safe. For example, when emplacing a raw new expression in a
container of smart pointers, the memory will be leaked if emplace_back throws an exception.