Namespaces
Variants

std::unordered_map<Key,T,Hash,KeyEqual,Allocator>:: try_emplace

From cppreference.net

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 无法通过对应表达式 原位构造 unordered_map 中,则行为未定义。
3) 此重载仅在满足以下所有条件时参与重载决议:
如果 hash_function ( ) ( u. first ) ! = hash_function ( ) ( k ) || contains ( u. first ) true ,则行为未定义,其中 u 是要插入的新元素。
6) 此重载仅当 Hash :: is_transparent KeyEqual :: is_transparent 均有效且各自表示一个类型时,才参与重载决议。
如果 hash_function ( ) ( u. first ) ! = hash_function ( ) ( k ) || contains ( u. first ) true ,则行为未定义,其中 u 是要插入的新元素。

如果在操作后新元素数量大于旧的 max_load_factor() * bucket_count() 将发生重新哈希。
如果发生重新哈希(由于插入操作),所有迭代器将失效。否则(未发生重新哈希),迭代器不会失效。

目录

参数

k - 用于查找且在未找到时插入的键
hint - 指向新元素将插入位置之前的迭代器
args - 要转发给元素构造函数的参数

返回值

1-3) emplace 相同:
返回一个由迭代器和布尔值组成的 pair,其中迭代器指向被插入元素(或阻止插入的元素),布尔值当且仅当插入成功时被设置为 true
4-6) emplace_hint 相同:
返回指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。

复杂度

1-3) emplace 相同:
平均情况下具有常数级复杂度,最坏情况与容器大小呈线性关系。
4-6) emplace_hint 相同:
平均情况下具有常数级摊销复杂度,最坏情况与容器大小呈线性关系。

注解

insert emplace 不同,这些函数在插入未发生时不会从右值参数移动,这使得操作值为仅移动类型的映射(例如 std:: unordered_map < std:: string , std:: unique_ptr < foo >> )更为简便。此外, try_emplace 将键和 mapped_type 的参数分开处理,这与需要构造 value_type (即 std::pair )参数的 emplace 不同。

重载版本 ( 3 ) ( 6 ) 可以在不构造 Key 类型对象的情况下调用。

功能测试 标准 功能特性
__cpp_lib_unordered_map_try_emplace 201411L (C++17) std::unordered_map::try_emplace ,
std::unordered_map::insert_or_assign
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) 有序 无序 关联式 容器 中剩余成员函数的异构重载。重载版本 ( 3 ) ( 6 )

示例

#include <iostream>
#include <string>
#include <unordered_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::unordered_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

参阅

原位构造元素
(公开成员函数)
使用提示原位构造元素
(公开成员函数)
插入元素 或节点 (C++17 起)
(公开成员函数)