Spec-Zone.ru › C++

std::map<Key,T,Compare,Allocator>::try_emplace

template< class... Args >
std::pair<iterator, bool> try_emplace( const Key& k, Args&&... args );
(1) (начиная с C++17)
template< class... Args >
std::pair<iterator, bool> try_emplace( Key&& k, Args&&... args );
(2) (начиная с C++17)
template< class K, class... Args >
std::pair<iterator, bool> try_emplace( K&& k, Args&&... args );
(3) (начиная с C++26)
template< class... Args >
iterator try_emplace( const_iterator hint, const Key& k, Args&&... args );
(4) (начиная с C++17)
template< class... Args >
iterator try_emplace( const_iterator hint, Key&& k, Args&&... args );
(5) (начиная с C++17)
template< class K, class... Args >
iterator try_emplace( const_iterator hint, K&& k, Args&&... args );
(6) (начиная с C++26)

Если эквивалентный k ключ уже существует в контейнере, ничего не происходит. В противном случае в контейнер вставляется новый элемент с ключом k и значением, сконструированным с помощью args. В этом случае:

1) Ведёт себя как emplace, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(k),
           std::forward_as_tuple(std::forward<Args>(args)...))
2) Ведёт себя как emplace, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(std::move(k)),
           std::forward_as_tuple(std::forward<Args>(args)...))
3) Ведёт себя как emplace, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(std::forward<K>(k)),
           std::forward_as_tuple(std::forward<Args>(args)...))
4) Ведёт себя как emplace_hint, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(k),
           std::forward_as_tuple(std::forward<Args>(args)...))
5) Ведёт себя как emplace_hint, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(std::move(k)),
           std::forward_as_tuple(std::forward<Args>(args)...))
6) Ведёт себя как emplace_hint, за исключением того, что элемент конструируется следующим образом:
value_type(std::piecewise_construct,
           std::forward_as_tuple(std::forward<K>(k)),
           std::forward_as_tuple(std::forward<Args>(args)...))
1-6) Если value_type не является EmplaceConstructible в map из соответствующего выражения, поведение не определено.
3) Эта перегрузка участвует в разрешении перегрузки, только если выполнены все следующие условия:
  • std::is_convertible_v<K&&, const_iterator> и std::is_convertible_v<K&&, iterator> являются false.
  • Квалифицированное имя Compare::is_transparent корректно и обозначает тип.
Если equal_range(u.first) == equal_range(k) является false, поведение не определено, где u — новый вставляемый элемент.
6) Эта перегрузка участвует в разрешении перегрузки, только если квалифицированное имя Compare::is_transparent корректно и обозначает тип.
Если equal_range(u.first) == equal_range(k) является false, поведение не определено, где u — новый вставляемый элемент.

Итераторы и ссылки не инвалидируются.

Параметры

k - ключ, используемый как для поиска, так и для вставки, если он не найден
hint - итератор на позицию, перед которой будет вставлен новый элемент
args - аргументы, передаваемые конструктору элемента

Возвращаемое значение

1-3) То же, что и у emplace:
Пара, состоящая из итератора на вставленный элемент (или на элемент, помешавший вставке) и значения типа bool, равного true тогда и только тогда, когда произошла вставка.
4-6) То же, что и у emplace_hint:
Итератор на вставленный элемент или на элемент, помешавший вставке.

Сложность

1-3) То же, что и у emplace:
Логарифмическая относительно размера контейнера.
4-6) То же, что и у emplace_hint:
В общем случае логарифмическая относительно размера контейнера, но амортизированная константная, если новый элемент вставляется непосредственно перед hint.

Примечания

В отличие от insert или emplace, эти функции не перемещают аргументы-значения rvalue, если вставка не происходит. Это упрощает работу с map, значения которых имеют типы, допускающие только перемещение, например std::map<std::string,std::unique_ptr<foo>>. Кроме того, try_emplace обрабатывает ключ и аргументы для mapped_type по отдельности, в отличие от emplace, которому требуются аргументы для конструирования value_type (то есть std::pair).

Перегрузки (3,6) можно вызвать без конструирования объекта типа Key.

Макрос проверки поддержки функции Значение Стандарт Функция
__cpp_lib_map_try_emplace 201411L (C++17) std::map::try_emplace, std::map::insert_or_assign
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) Гетерогенные перегрузки для остальных функций-членов в упорядоченных и неупорядоченных ассоциативных контейнерах. Перегрузки (3) и (6).

Пример

#include <iostream>
#include <string>
#include <map>
#include <utility>

void print_node(const auto& node)
{
    std::cout << '[' << node.first << "] = " << node.second << '\n';
}

void print_result(auto const& pair)
{
    std::cout << (pair.second ? "inserted: " : "ignored:  ");
    print_node(*pair.first);
}

int main()
{
    using namespace std::literals;
    std::map<std::string, std::string> m;
    
    print_result(m.try_emplace("a", "a"s));
    print_result(m.try_emplace("b", "abcd"));
    print_result(m.try_emplace("c", 10, 'c'));
    print_result(m.try_emplace("c", "Won't be inserted"));
    
    for (const auto& p : m)
        print_node(p);
}

Вывод:

inserted: [a] = a
inserted: [b] = abcd
inserted: [c] = cccccccccc
ignored:  [c] = cccccccccc
[a] = a
[b] = abcd
[c] = cccccccccc

См. также

emplace
(C++11)
конструирует элемент на месте
(открытая функция-член)
emplace_hint
(C++11)
конструирует элементы на месте, используя подсказку
(открытая функция-член)
insert
вставляет элементы или узлы(начиная с C++17)
(открытая функция-член)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/map/try_emplace

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API