148 lines
4.2 KiB
ReStructuredText
148 lines
4.2 KiB
ReStructuredText
.. title:: clang-tidy - modernize-use-emplace
|
|
|
|
modernize-use-emplace
|
|
=====================
|
|
|
|
The check flags insertions to an STL-style container done by calling the
|
|
``push_back`` method with an explicitly-constructed temporary of the container
|
|
element type. In this case, the corresponding ``emplace_back`` method
|
|
results in less verbose and potentially more efficient code.
|
|
Right now the check doesn't support ``push_front`` and ``insert``.
|
|
It also doesn't support ``insert`` functions for associative containers
|
|
because replacing ``insert`` with ``emplace`` may result in
|
|
`speed regression <http://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.
|
|
|
|
By default only ``std::vector``, ``std::deque``, ``std::list`` are considered.
|
|
This list can be modified using the :option:`ContainersWithPushBack` option.
|
|
|
|
Before:
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<MyClass> v;
|
|
v.push_back(MyClass(21, 37));
|
|
|
|
std::vector<std::pair<int, int>> w;
|
|
|
|
w.push_back(std::pair<int, int>(21, 37));
|
|
w.push_back(std::make_pair(21L, 37L));
|
|
|
|
After:
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<MyClass> v;
|
|
v.emplace_back(21, 37);
|
|
|
|
std::vector<std::pair<int, int>> w;
|
|
w.emplace_back(21, 37);
|
|
w.emplace_back(21L, 37L);
|
|
|
|
By default, the check is able to remove unnecessary ``std::make_pair`` and
|
|
``std::make_tuple`` calls from ``push_back`` calls on containers of
|
|
``std::pair`` and ``std::tuple``. Custom tuple-like types can be modified by
|
|
the :option:`TupleTypes` option; custom make functions can be modified by the
|
|
:option:`TupleMakeFunctions` option.
|
|
|
|
The other situation is when we pass arguments that will be converted to a type
|
|
inside a container.
|
|
|
|
Before:
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<boost::optional<std::string> > v;
|
|
v.push_back("abc");
|
|
|
|
After:
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<boost::optional<std::string> > v;
|
|
v.emplace_back("abc");
|
|
|
|
|
|
In some cases the transformation would be valid, but the code wouldn't be
|
|
exception safe. In this case the calls of ``push_back`` won't be replaced.
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<std::unique_ptr<int>> v;
|
|
v.push_back(std::unique_ptr<int>(new int(0)));
|
|
auto *ptr = new int(1);
|
|
v.push_back(std::unique_ptr<int>(ptr));
|
|
|
|
This is because replacing it with ``emplace_back`` could cause a leak of this
|
|
pointer if ``emplace_back`` would throw exception before emplacement (e.g. not
|
|
enough memory to add a new element).
|
|
|
|
For more info read item 42 - "Consider emplacement instead of insertion." of
|
|
Scott Meyers "Effective Modern C++".
|
|
|
|
The default smart pointers that are considered are ``std::unique_ptr``,
|
|
``std::shared_ptr``, ``std::auto_ptr``. To specify other smart pointers or
|
|
other classes use the :option:`SmartPointers` option.
|
|
|
|
|
|
Check also doesn't fire if any argument of the constructor call would be:
|
|
|
|
- a bit-field (bit-fields can't bind to rvalue/universal reference)
|
|
|
|
- a ``new`` expression (to avoid leak)
|
|
|
|
- if the argument would be converted via derived-to-base cast.
|
|
|
|
This check requires C++11 or higher to run.
|
|
|
|
Options
|
|
-------
|
|
|
|
.. option:: ContainersWithPushBack
|
|
|
|
Semicolon-separated list of class names of custom containers that support
|
|
``push_back``.
|
|
|
|
.. option:: IgnoreImplicitConstructors
|
|
|
|
When non-zero, the check will ignore implicitly constructed arguments of
|
|
``push_back``, e.g.
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<std::string> v;
|
|
v.push_back("a"); // Ignored when IgnoreImplicitConstructors is ``1``.
|
|
|
|
Default is ``0``.
|
|
|
|
.. option:: SmartPointers
|
|
|
|
Semicolon-separated list of class names of custom smart pointers.
|
|
|
|
.. option:: TupleTypes
|
|
|
|
Semicolon-separated list of ``std::tuple``-like class names.
|
|
|
|
.. option:: TupleMakeFunctions
|
|
|
|
Semicolon-separated list of ``std::make_tuple``-like function names. Those
|
|
function calls will be removed from ``push_back`` calls and turned into
|
|
``emplace_back``.
|
|
|
|
Example
|
|
^^^^^^^
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<MyTuple<int, bool, char>> x;
|
|
x.push_back(MakeMyTuple(1, false, 'x'));
|
|
|
|
transforms to:
|
|
|
|
.. code-block:: c++
|
|
|
|
std::vector<MyTuple<int, bool, char>> x;
|
|
x.emplace_back(1, false, 'x');
|
|
|
|
when :option:`TupleTypes` is set to ``MyTuple`` and :option:`TupleMakeFunctions`
|
|
is set to ``MakeMyTuple``.
|