72 lines
2.1 KiB
Plaintext
72 lines
2.1 KiB
Plaintext
== Why is this an issue?
|
||
|
||
``++emplace++`` enables you to avoid copying or moving the value you are about to insert and, instead, it constructs it in-place with the arguments provided.
|
||
|
||
|
||
Prefer using ``++emplace++``, or ``++emplace_hint++`` if all the conditions hold:
|
||
|
||
* You are inserting a single value.
|
||
* You are constructing a fresh temporary value just to insert it into the set.
|
||
* You expect that the key is not in the set.
|
||
|
||
You should keep the ``++insert++`` in any of the cases below:
|
||
|
||
* You are inserting multiple values in one shot.
|
||
* You are inserting a pre-existing value that is constructed for another purpose.
|
||
* You are inserting an object that is cheap to move or to copy (e.g., an integer).
|
||
* The key you are inserting is likely to be in the set (in this case by using ``++insert++`` you avoid creating a useless temporary node).
|
||
|
||
This rule detects calls to ``++insert++`` that lead to the creation of a large temporary object that can be avoided by using the ``++emplace++`` member function.
|
||
|
||
|
||
=== Noncompliant code example
|
||
|
||
[source,cpp]
|
||
----
|
||
struct A {
|
||
int x;
|
||
std::array<std::string, 100> more;// Expensive to copy or move
|
||
public:
|
||
A(int x, const std::string& more) : x(x), more({more}) {}
|
||
bool operator<(A const &other) const {
|
||
return x < other.x;
|
||
}
|
||
};
|
||
std::array<std::string, 3> strs = {"big brown fox", "little kitten", "regular human"};
|
||
void f() {
|
||
std::set<A> set;
|
||
for (int i = 0; i < 1'000'000; ++i) {
|
||
set.insert(A{i, strs[i%3]});// Noncompliant
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
=== Compliant solution
|
||
|
||
[source,cpp]
|
||
----
|
||
struct A {
|
||
int x;
|
||
std::array<std::string, 100> more;// Expensive to copy or move
|
||
public:
|
||
A(int x, const std::string& more) : x(x), more({more}) {}
|
||
bool operator<(A const &other) const {
|
||
return x < other.x;
|
||
}
|
||
};
|
||
std::array<std::string, 3> strs = {"big brown fox", "little kitten", "regular human"};
|
||
void f() {
|
||
std::set<A> set;
|
||
for (int i = 0; i < 1'000'000; ++i) {
|
||
set.emplace(i, strs[i%3]);// Compliant
|
||
}
|
||
}
|
||
----
|
||
|
||
|
||
=== Exceptions
|
||
|
||
You should keep ``++insert++`` for exception safety if your key type is a smart pointer and the argument is a new expression.
|
||
|