std::map<Key,T,Compare,Allocator>::emplace_hint
From cppreference.com
C++
Feature test macros (C++20)
Concepts library (C++20)
Metaprogramming library (C++11)
Ranges library (C++20)
Filesystem library (C++17)
Concurrency support library (C++11)
Execution control library (C++26)
Containers library
(C++17)
(C++11)
(C++26)
(C++26)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++23)
(C++23)
(C++23)
(C++23)
(C++20)
(C++23)
Tables
std::map
(C++11)
(C++11)
(C++11)
(C++11)
(C++17)
(C++17)
(C++23)
(C++17)
(C++11)
map::emplace_hint
(C++11)
(C++17)
(C++20)
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)
Deduction guides (C++17)
template< class... Args >
iterator emplace_hint( const_iterator hint, Args&&... args );
(since C++11) iterator emplace_hint( const_iterator hint, Args&&... args );
(constexpr since C++26)
Inserts a new element into the container as close as possible to the position just before hint.
The constructor of value_type
(i.e., std::pair <const Key, T>) is called with exactly the same arguments as supplied to the function, forwarded with std::forward <Args>(args)....
No iterators or references are invalidated.
[edit] Parameters
hint
-
iterator to the position before which the new element will be inserted
args
-
arguments to forward to the constructor of the element
[edit] Return value
An iterator to the inserted element, or to the element that prevented the insertion.
[edit] Exceptions
If an exception is thrown for any reason, this function has no effect (strong exception safety guarantee).
[edit] Complexity
Logarithmic in the size of the container in general, but amortized constant if the new element is inserted just before hint.
[edit] Example
Run this code
#include <chrono> #include <cstddef> #include <functional> #include <iomanip> #include <iostream> #include <map> const int n_operations = 100'500'0; std::size_t map_emplace() { std::map <int, char> map; for (int i = 0; i < n_operations; ++i) map.emplace(i, 'a'); return map.size(); } std::size_t map_emplace_hint() { std::map <int, char> map; auto it = map.begin(); for (int i = 0; i < n_operations; ++i) { map.emplace_hint(it, i, 'b'); it = map.end(); } return map.size(); } std::size_t map_emplace_hint_wrong() { std::map <int, char> map; auto it = map.begin(); for (int i = n_operations; i > 0; --i) { map.emplace_hint(it, i, 'c'); it = map.end(); } return map.size(); } std::size_t map_emplace_hint_corrected() { std::map <int, char> map; auto it = map.begin(); for (int i = n_operations; i > 0; --i) { map.emplace_hint(it, i, 'd'); it = map.begin(); } return map.size(); } std::size_t map_emplace_hint_closest() { std::map <int, char> map; auto it = map.begin(); for (int i = 0; i < n_operations; ++i) it = map.emplace_hint(it, i, 'e'); return map.size(); } double time_it(std::function <std::size_t ()> map_test, std::string what = "", double ratio = 0.0) { const auto start = std::chrono::system_clock::now (); const std::size_t map_size = map_test(); const auto stop = std::chrono::system_clock::now (); std::chrono::duration <double, std::milli > time = stop - start; if (what.size() && map_size) std::cout << std::setw (8) << time << " for " << what << " (ratio: " << (ratio == 0.0 ? 1.0 : ratio / time.count()) << ")\n"; return time.count(); } int main() { std::cout << std::fixed << std::setprecision (2); time_it(map_emplace); // cache warmup const auto x = time_it(map_emplace, "plain emplace"); time_it(map_emplace_hint, "emplace with correct hint", x); time_it(map_emplace_hint_wrong, "emplace with wrong hint", x); time_it(map_emplace_hint_corrected, "corrected emplace", x); time_it(map_emplace_hint_closest, "emplace using returned iterator", x); }
Possible output:
365.08ms for plain emplace (ratio: 1.00) 96.54ms for emplace with correct hint (ratio: 3.78) 409.40ms for emplace with wrong hint (ratio: 0.89) 85.57ms for corrected emplace (ratio: 4.27) 84.31ms for emplace using returned iterator (ratio: 4.33)