rspec/rules/S6033/cfamily/rule.adoc

72 lines
2.1 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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