xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/modernize/use-emplace.rst (revision b8655f7ff286b9ebcd97cdd24b9c8eb5b89b9651)
1.. title:: clang-tidy - modernize-use-emplace
2
3modernize-use-emplace
4=====================
5
6The check flags insertions to an STL-style container done by calling the
7``push_back``, ``push``, or ``push_front`` methods with an
8explicitly-constructed temporary of the container element type. In this case,
9the corresponding ``emplace`` equivalent methods result in less verbose and
10potentially more efficient code.  Right now the check doesn't support
11``insert``. It also doesn't support ``insert`` functions for associative
12containers because replacing ``insert`` with ``emplace`` may result in
13`speed regression <https://htmlpreview.github.io/?https://github.com/HowardHinnant/papers/blob/master/insert_vs_emplace.html>`_, but it might get support with some addition flag in the future.
14
15The :option:`ContainersWithPushBack`, :option:`ContainersWithPush`, and
16:option:`ContainersWithPushFront` options are used to specify the container
17types that support the ``push_back``, ``push``, and ``push_front`` operations
18respectively. The default values for these options are as follows:
19
20* :option:`ContainersWithPushBack`: ``std::vector``, ``std::deque``, and ``std::list``.
21* :option:`ContainersWithPush`: ``std::stack``, ``std::queue``, and ``std::priority_queue``.
22* :option:`ContainersWithPushFront`: ``std::forward_list``, ``std::list``, and ``std::deque``.
23
24This check also reports when an ``emplace``-like method is improperly used,
25for example using ``emplace_back`` while also calling a constructor. This
26creates a temporary that requires at best a move and at worst a copy. Almost all
27``emplace``-like functions in the STL are covered by this, with ``try_emplace``
28on ``std::map`` and ``std::unordered_map`` being the exception as it behaves
29slightly differently than all the others. More containers can be added with the
30:option:`EmplacyFunctions` option, so long as the container defines a
31``value_type`` type, and the ``emplace``-like functions construct a
32``value_type`` object.
33
34Before:
35
36.. code-block:: c++
37
38    std::vector<MyClass> v;
39    v.push_back(MyClass(21, 37));
40    v.emplace_back(MyClass(21, 37));
41
42    std::vector<std::pair<int, int>> w;
43
44    w.push_back(std::pair<int, int>(21, 37));
45    w.push_back(std::make_pair(21L, 37L));
46    w.emplace_back(std::make_pair(21L, 37L));
47
48After:
49
50.. code-block:: c++
51
52    std::vector<MyClass> v;
53    v.emplace_back(21, 37);
54    v.emplace_back(21, 37);
55
56    std::vector<std::pair<int, int>> w;
57    w.emplace_back(21, 37);
58    w.emplace_back(21L, 37L);
59    w.emplace_back(21L, 37L);
60
61By default, the check is able to remove unnecessary ``std::make_pair`` and
62``std::make_tuple`` calls from ``push_back`` calls on containers of
63``std::pair`` and ``std::tuple``. Custom tuple-like types can be modified by
64the :option:`TupleTypes` option; custom make functions can be modified by the
65:option:`TupleMakeFunctions` option.
66
67The other situation is when we pass arguments that will be converted to a type
68inside a container.
69
70Before:
71
72.. code-block:: c++
73
74    std::vector<boost::optional<std::string> > v;
75    v.push_back("abc");
76
77After:
78
79.. code-block:: c++
80
81    std::vector<boost::optional<std::string> > v;
82    v.emplace_back("abc");
83
84
85In some cases the transformation would be valid, but the code wouldn't be
86exception safe. In this case the calls of ``push_back`` won't be replaced.
87
88.. code-block:: c++
89
90    std::vector<std::unique_ptr<int>> v;
91    v.push_back(std::unique_ptr<int>(new int(0)));
92    auto *ptr = new int(1);
93    v.push_back(std::unique_ptr<int>(ptr));
94
95This is because replacing it with ``emplace_back`` could cause a leak of this
96pointer if ``emplace_back`` would throw exception before emplacement (e.g. not
97enough memory to add a new element).
98
99For more info read item 42 - "Consider emplacement instead of insertion." of
100Scott Meyers "Effective Modern C++".
101
102The default smart pointers that are considered are ``std::unique_ptr``,
103``std::shared_ptr``, ``std::auto_ptr``. To specify other smart pointers or
104other classes use the :option:`SmartPointers` option.
105
106
107Check also doesn't fire if any argument of the constructor call would be:
108
109  - a bit-field (bit-fields can't bind to rvalue/universal reference)
110
111  - a ``new`` expression (to avoid leak)
112
113  - if the argument would be converted via derived-to-base cast.
114
115This check requires C++11 or higher to run.
116
117Options
118-------
119
120.. option:: ContainersWithPushBack
121
122   Semicolon-separated list of class names of custom containers that support
123   ``push_back``.
124
125.. option:: ContainersWithPush
126
127   Semicolon-separated list of class names of custom containers that support
128   ``push``.
129
130.. option:: ContainersWithPushFront
131
132   Semicolon-separated list of class names of custom containers that support
133   ``push_front``.
134
135.. option:: IgnoreImplicitConstructors
136
137    When `true`, the check will ignore implicitly constructed arguments of
138    ``push_back``, e.g.
139
140    .. code-block:: c++
141
142        std::vector<std::string> v;
143        v.push_back("a"); // Ignored when IgnoreImplicitConstructors is `true`.
144
145    Default is `false`.
146
147.. option:: SmartPointers
148
149   Semicolon-separated list of class names of custom smart pointers.
150
151.. option:: TupleTypes
152
153    Semicolon-separated list of ``std::tuple``-like class names.
154
155.. option:: TupleMakeFunctions
156
157    Semicolon-separated list of ``std::make_tuple``-like function names. Those
158    function calls will be removed from ``push_back`` calls and turned into
159    ``emplace_back``.
160
161.. option:: EmplacyFunctions
162
163    Semicolon-separated list of containers without their template parameters
164    and some ``emplace``-like method of the container. Example:
165    ``vector::emplace_back``. Those methods will be checked for improper use and
166    the check will report when a temporary is unnecessarily created.
167
168Example
169^^^^^^^
170
171.. code-block:: c++
172
173  std::vector<MyTuple<int, bool, char>> x;
174  x.push_back(MakeMyTuple(1, false, 'x'));
175  x.emplace_back(MakeMyTuple(1, false, 'x'));
176
177transforms to:
178
179.. code-block:: c++
180
181  std::vector<MyTuple<int, bool, char>> x;
182  x.emplace_back(1, false, 'x');
183  x.emplace_back(1, false, 'x');
184
185when :option:`TupleTypes` is set to ``MyTuple``, :option:`TupleMakeFunctions`
186is set to ``MakeMyTuple``, and :option:`EmplacyFunctions` is set to
187``vector::emplace_back``.
188