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