迭代器
返回指向容器第一个元素的迭代器
std::map<Key,T,Compare,Allocator>::begin,
std::map<Key,T,Compare,Allocator>::cbegin
iterator begin(); (C++11 前)
iterator begin() noexcept; (C++11 起)
const_iterator begin() const; (C++11 前)
const_iterator begin() const noexcept; (C++11 起)
const_iterator cbegin() const noexcept; (C++11 起)
参数
(无)
返回值
指向首元素的迭代器。
复杂度
常数。
返回指向容器尾端的迭代器
std::map<Key,T,Compare,Allocator>::end,
std::map<Key,T,Compare,Allocator>::cend
iterator end(); (C++11 前)
iterator end() noexcept; (C++11 起)
const_iterator end() const; (C++11 前)
const_iterator end() const noexcept; (C++11 起)
const_iterator cend() const noexcept; (C++11 起)
返回指向容器末元素后一元素的迭代器。
此元素表现为占位符;试图访问它导致未定义行为。
参数
(无)
返回值
指向后随最后元素的迭代器。
复杂度
常数。
返回指向容器最后元素的逆向迭代器
std::map<Key,T,Compare,Allocator>::rbegin,
std::map<Key,T,Compare,Allocator>::crbegin
reverse_iterator rbegin(); (C++11 前)
reverse_iterator rbegin() noexcept; (C++11 起)
const_reverse_iterator rbegin() const; (C++11 前)
const_reverse_iterator rbegin() const noexcept; (C++11 起)
const_reverse_iterator crbegin() const noexcept; (C++11 起)
返回指向逆向容器首元素的逆向迭代器。它对应非逆向容器的末元素。
参数
(无)
返回值
指向首元素的逆向迭代器。
复杂度
常数。
返回指向前端的逆向迭代器
std::map<Key,T,Compare,Allocator>::rend,
std::map<Key,T,Compare,Allocator>::crend
reverse_iterator rend(); (C++11 前)
reverse_iterator rend() noexcept; (C++11 起)
const_reverse_iterator rend() const; (C++11 前)
const_reverse_iterator rend() const noexcept; (C++11 起)
const_reverse_iterator crend() const noexcept; (C++11 起)
返回指向逆向容器末元素后一元素的逆向迭代器。它对应非逆向容器首元素的前一元素。此元素表现为占位符,试图访问它导致未定义行为。
参数
(无)
返回值
指向末元素后一元素的逆向迭代器。
复杂度
常数。
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
// 遍历容器, const_iterator
std::cout << "const_iterator:\n";
for (map<uint16_t, string>::const_iterator it = map1.cbegin(); it != map1.cend(); it++)
{
cout << "key: " << it->first << ", value: " << it->second << endl;
}
std::cout << "const_iterator:\n";
for (map<uint16_t, string>::const_reverse_iterator it = map1.crbegin(); it != map1.crend(); it++)
{
cout << "key: " << it->first << ", value: " << it->second << endl;
}
std::cout << "begin(): " << std::hex << (int)&*map1.begin() << std::endl;
std::cout << "cbegin(): " << std::hex << (int)&*map1.cbegin() << std::endl;
std::cout << "end(): " << std::hex << (int)&*map1.end() << std::endl;
std::cout << "cend(): " << std::hex << (int)&*map1.cend() << std::endl;
std::cout << "rbegin(): " << std::hex << (int)&*map1.rbegin() << std::endl;
std::cout << "crbegin(): " << std::hex << (int)&*map1.crbegin() << std::endl;
std::cout << "rend(): " << std::hex << (int)&*map1.rend() << std::endl;
std::cout << "crend(): " << std::hex << (int)&*map1.crend() << std::endl;
修改器
清除内容
std::map<Key,T,Compare,Allocator>::clear
void clear(); (C++11 前)
void clear() noexcept; (C++11 起)
从容器擦除所有元素。此调用后 size() 返回零。
非法化任何指代所含元素的引用、指针或迭代器。任何尾后迭代器保持合法。
参数
(无)
返回值
(无)
复杂度
与容器大小,即元素数成线性。
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("clear before", map1);
map1.clear();
cout << "map1: " << (map1.empty() ? "empty" : "not empty");
插入元素或结点
std::map<Key,T,Compare,Allocator>::insert
std::pair<iterator,bool> insert( const value_type& value ); (1)
template< class P > std::pair<iterator,bool> insert( P&& value ); (2)
插入 value
。重载 (2) 等价于 emplace(std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。
返回由指向被插入元素的迭代器(或阻止插入的元素的迭代器)和指代插入是否发生的 bool 组成的 pair 。
若任何操作抛出异常,则插入无效果(强异常保证)。
与容器大小成对数, O(log(size()))
。
iterator insert( iterator hint, const value_type& value ); (C++11 前)
iterator insert( const_iterator hint, const value_type& value ); (C++11 起)
template< class P >
iterator insert( const_iterator hint, P&& value ); (5) (C++11 起)
插入 value
到尽可能接近,恰好前于(C++11 起) hint
的位置。重载 (4) 等价于 emplace_hint(hint, std::forward<P>(value)) ,且仅若 std::is_constructible<value_type, P&&>::value == true 才参与重载决议。
返回指向被插入元素的迭代器,或指向阻止插入的元素的迭代器。
若插入恰好发生在 hint 后的位置则为均摊常数,否则与容器大小成对数。(C++11 前)
若插入恰好发生在 hint 前的位置则为均摊常数,否则与容器大小成对数。(C++11 起)
void insert( std::initializer_list<value_type> ilist ); (8) (C++11 起)
插入来自 initializer_list ilist
的元素。若范围中的多个元素拥有比较等价的关键,则插入哪个元素是未指定的
若任何操作抛出异常,则程序在合法状态(基础异常保证)。
O(N*log(size() + N))
,其中 N 是要插入的元素数。
参数
hint | - |
| ||||
value | - | 要插入的值 | ||||
first, last | - | 要插入的元素范围 | ||||
ilist | - | 插入值来源的 initializer_list |
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
print_Map("insert before", map1);
std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.insert({4, "D"});
cout << "insert " << (itI.second ? "success" : "fail") ;
cout << " key: " << itI.first->first << " value: " << itI.first->second << endl;
print_Map("insert after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
cout << "find key: " << pIt->first << " value: " << pIt->second << endl;
map<uint16_t, string>::const_iterator nIt = map1.insert(pIt, {5, "E"});
cout << "insert key: " << nIt->first << " value: " << nIt->second << endl;
print_Map("insert after", map1);
map<uint16_t, string> map2{{6, "F"}, {7, "H"}};
map2.insert(map1.begin(), map1.end());
print_Map("map2 insert after", map2);
原位构造元素
std::map<Key,T,Compare,Allocator>::emplace
template< class... Args >
std::pair<iterator,bool> emplace( Args&&... args ); (C++11 起)
若容器中无拥有该关键的元素,则插入以给定的 args
原位构造的新元素到容器。
细心地使用 emplace
允许在构造新元素的同时避免不必要的复制或移动操作。 准确地以与提供给 emplace
者相同的参数,通过 std::forward<Args>(args)... 转发调用新元素(即 std::pair<const Key, T> )的构造函数。 即使容器中已有拥有该关键的元素,也可能构造元素,该情况下新构造的元素将被立即销毁。
没有迭代器或引用被非法化。
参数
args | - | 要转发给元素构造函数的参数 |
返回值
返回由指向被插入元素,或若不发生插入则为既存元素的迭代器,和指代插入是否发生的 bool (若发生插入则为 true ,否则为 false )。
异常
若任何操作抛出异常,则此函数无效果。
复杂度
与容器大小成对数。
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
print_Map("emplace before", map1);
std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.emplace(make_pair(4, "D"));
cout << "emplace " << (itI.second ? "success" : "fail") ;
cout << " key: " << itI.first->first << " value: " << itI.first->second << endl;
print_Map("emplace after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
map<uint16_t, string>::const_iterator nIt = map1.emplace_hint(pIt, make_pair(5, "E"));
cout << "emplace_hint key: " << nIt->first << " value: " << nIt->second << endl;
print_Map("emplace_hint after", map1);
擦除元素
std::map<Key,T,Compare,Allocator>::erase
void erase( iterator pos ); (C++11 前)
iterator erase( const_iterator pos ); (C++11 起)
void erase( iterator first, iterator last ); (C++11 前)
iterator erase( const_iterator first, const_iterator last );(C++11 起)
size_type erase( const key_type& key ); (3)
从容器移除指定的元素。
1) 移除位于 pos
的元素。
2) 移除范围 [first; last)
中的元素,它必须是 *this 中的合法范围。
3) 移除关键等于 key
的元素(若存在一个)。
指向被擦除元素的引用和迭代器被非法化。其他引用和迭代器不受影响。
迭代器 pos
必须合法且可解引用。从而 end() 迭代器(合法,但不可解引用)不能用作 pos
所用的值。
参数
pos | - | 指向要移除的元素的迭代器 |
first, last | - | 要移除的元素范围 |
key | - | 要移除的元素关键值 |
返回值
1-2) 后随最后被移除的元素的迭代器。
3) 被移除的元素数。
异常
1,2) (无)
3) 任何 Compare
对象所抛的异常
复杂度
给定 map
的实例 c
:
1) 均摊常数
2) log(c.size()) + std::distance(first, last)
3) log(c.size()) + c.count(k)
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("erase before", map1);
size_t ct = map1.erase(3);
cout << "erase size: " << ct << std::endl;
ct = map1.erase(3);
cout << "erase size: " << ct << std::endl;
print_Map("map1 erase after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
map<uint16_t, string>::const_iterator eIt = map1.erase(pIt);
cout << "erase key: " << eIt->first << " value: " << eIt->second << endl;
print_Map("map1 erase after", map1);
map<uint16_t, string> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("map2 erase before", map2);
map2.erase(map2.begin(), map2.end());
print_Map("map2 erase after", map2);
交换内容
std::map<Key,T,Compare,Allocator>::swap
void swap( map& other ); (C++17 前)
void swap( map& other ) noexcept(/* see below */); (C++17 起)
将内容与 other
的交换。不在单个元素上调用任何移动、复制或交换操作。
所有迭代器和引用保持合法。尾后迭代器被非法化。
Pred
对象必须可交换 (Swappable) ,并用非成员 swap
的非限定调用交换它们。
若 std::allocator_traits<allocator_type>::propagate_on_container_swap::value 为 true ,则用非成员 | (C++11 起) |
参数
other | - | 要与之交换内容的容器 |
返回值
(无)
异常
任何 | (C++17 前) |
noexcept 规定: noexcept(std::allocator_traits<Allocator>::is_always_equal::value | (C++17 起) |
复杂度
常数。
示例
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
map<uint16_t, string> map2{{4, "D"}, {5, "E"}};
print_Map("map1 swap before", map1);
print_Map("map2 swap before", map2);
map1.swap(map2);
print_Map("map1 swap after", map1);
print_Map("map2 swap after", map2);
代码汇总
#include <iostream>
#include <map>
#include <string>
using namespace std;
struct myCompare
{
bool operator()(const uint16_t a, const uint16_t b) const
{
return (a > b);
}
myCompare() {}
};
template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
void print_Map(const string &name, const map<_Key, _Tp, _Compare, _Alloc> &tmap)
{
cout << name << ": \n";
for (const std::pair<const _Key, _Tp> it : tmap)
{
cout << "key: " << it.first << ", value: " << it.second << endl;
}
}
void constructorTest()
{
cout << "constructorTest() begin" << endl;
// 构造空容器
map<uint16_t, string> map1;
cout << "map1.size() : " << map1.size() << endl;
// 列表初始化,构造, 排序递增
map<uint16_t, string, std::less<uint16_t>> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("initializer_list, ASC", map2);
// 列表初始化,构造, 排序递减
map<uint16_t, string, std::greater<uint16_t>> map6{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("initializer_list, DESC", map6);
// 列表初始化,构造, 排序自定义
map<uint16_t, string, myCompare> map7{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("initializer_list, DESC", map7);
// 范围构造,排序递增
map<uint16_t, string, std::less<uint16_t>> map3(map2.begin(), map2.end());
print_Map("range, ASC", map3);
// 范围构造,排序递减
map<uint16_t, string, std::greater<uint16_t>> map8(map2.begin(), map2.end());
print_Map("range, DESC", map8);
// 拷贝构造,类型必须一致,包括排序,排序递增
map<uint16_t, string, std::less<uint16_t>> map4(map3);
print_Map("copy, ASC", map4);
// 拷贝构造,排序递增
map<uint16_t, string, std::greater<uint16_t>> map9(map8);
print_Map("copy, DESC", map9);
// 赋值构造,类型必须一致,包括排序,排序递增
map<uint16_t, string, std::less<uint16_t>> map10 = map4;
print_Map("assignment , ASC", map10);
// 赋值构造,类型必须一致,包括排序,排序递减
map<uint16_t, string, std::greater<uint16_t>> map11 = map9;
print_Map("assignment , DESC", map11);
cout << "constructorTest() end" << endl;
}
void elementAccessTest()
{
cout << "elementAccessTest() begin" << endl;
map<uint16_t, string, std::less<uint16_t>> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
cout << "at(key) : " << map1.at(1) << endl;
cout << "[key] : " << map1[2] << endl;
// map容器产生<6,"">节点
cout << "[key] : " << map1[6] << endl;
print_Map("[key] , ASC", map1);
// map容器产生<7,"H">节点
map1[7] = "H";
print_Map("[key] , ASC", map1);
// map容器key为1的节点value被替换为"K"
map1[1] = "K";
print_Map("[key] , ASC", map1);
cout << "elementAccessTest() end" << endl;
}
void capacityTest()
{
cout << "capacityTest begin" << endl;
map<uint16_t, string> map1;
cout << "map1: " << (map1.empty() ? "empty" : "not empty");
cout << "map1 size() " << map1.size() << endl;;
map1[1] = "A";
map1[2] = "B";
cout << "map1: " << (map1.empty() ? "empty" : "not empty");
cout << "map1 size() " << map1.size() << endl;;
cout << "map<uint16_t, string> max_size: " << map1.max_size() << std::endl;
map<uint16_t, uint16_t> map2;
cout << "map<uint16_t, uint16_t> max_size: " << map2.max_size() << std::endl;
map<string, uint16_t> map3;
cout << "map<string, uint16_t> max_size: " << map3.max_size() << std::endl;
map<string, string> map4;
cout << "map<string, string> max_size: " << map4.max_size() << std::endl;
cout << "capacityTest end" << endl;
}
void iteratorTest()
{
cout << "iteratorTest begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
// 遍历容器, const_iterator
std::cout << "const_iterator:\n";
for (map<uint16_t, string>::const_iterator it = map1.cbegin(); it != map1.cend(); it++)
{
cout << "key: " << it->first << ", value: " << it->second << endl;
}
std::cout << "const_iterator:\n";
for (map<uint16_t, string>::const_reverse_iterator it = map1.crbegin(); it != map1.crend(); it++)
{
cout << "key: " << it->first << ", value: " << it->second << endl;
}
std::cout << "begin(): " << std::hex << (int)&*map1.begin() << std::endl;
std::cout << "cbegin(): " << std::hex << (int)&*map1.cbegin() << std::endl;
std::cout << "end(): " << std::hex << (int)&*map1.end() << std::endl;
std::cout << "cend(): " << std::hex << (int)&*map1.cend() << std::endl;
std::cout << "rbegin(): " << std::hex << (int)&*map1.rbegin() << std::endl;
std::cout << "crbegin(): " << std::hex << (int)&*map1.crbegin() << std::endl;
std::cout << "rend(): " << std::hex << (int)&*map1.rend() << std::endl;
std::cout << "crend(): " << std::hex << (int)&*map1.crend() << std::endl;
cout << "iteratorTest end" << endl;
}
void clearTest()
{
cout << "clearTest() begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("clear before", map1);
map1.clear();
cout << "map1: " << (map1.empty() ? "empty" : "not empty");
cout << "clearTest() end" << endl;
}
void insertTest()
{
cout << "insertTest() begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
print_Map("insert before", map1);
std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.insert({4, "D"});
cout << "insert " << (itI.second ? "success" : "fail") ;
cout << " key: " << itI.first->first << " value: " << itI.first->second << endl;
print_Map("insert after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
cout << "find key: " << pIt->first << " value: " << pIt->second << endl;
map<uint16_t, string>::const_iterator nIt = map1.insert(pIt, {5, "E"});
cout << "insert key: " << nIt->first << " value: " << nIt->second << endl;
print_Map("insert after", map1);
map<uint16_t, string> map2{{6, "F"}, {7, "H"}};
map2.insert(map1.begin(), map1.end());
print_Map("map2 insert after", map2);
cout << "insertTest() end" << endl;
}
void emplaceTest()
{
cout << "emplaceTest() begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
print_Map("emplace before", map1);
std::pair<std::map<uint16_t, string>::iterator, bool> itI = map1.emplace(make_pair(4, "D"));
cout << "emplace " << (itI.second ? "success" : "fail") ;
cout << " key: " << itI.first->first << " value: " << itI.first->second << endl;
print_Map("emplace after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
map<uint16_t, string>::const_iterator nIt = map1.emplace_hint(pIt, make_pair(5, "E"));
cout << "emplace_hint key: " << nIt->first << " value: " << nIt->second << endl;
print_Map("emplace_hint after", map1);
cout << "emplaceTest() end" << endl;
}
void eraseTest()
{
cout << "eraseTest() begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("erase before", map1);
size_t ct = map1.erase(3);
cout << "erase size: " << ct << std::endl;
ct = map1.erase(3);
cout << "erase size: " << ct << std::endl;
print_Map("map1 erase after", map1);
map<uint16_t, string>::const_iterator pIt = map1.find(2);
map<uint16_t, string>::const_iterator eIt = map1.erase(pIt);
cout << "erase key: " << eIt->first << " value: " << eIt->second << endl;
print_Map("map1 erase after", map1);
map<uint16_t, string> map2{{1, "A"}, {2, "B"}, {3, "C"}, {4, "D"}, {5, "E"}};
print_Map("map2 erase before", map2);
map2.erase(map2.begin(), map2.end());
print_Map("map2 erase after", map2);
cout << "eraseTest() end" << endl;
}
void swapTest()
{
cout << "swapTest() begin" << endl;
map<uint16_t, string> map1{{1, "A"}, {2, "B"}, {3, "C"}};
map<uint16_t, string> map2{{4, "D"}, {5, "E"}};
print_Map("map1 swap before", map1);
print_Map("map2 swap before", map2);
map1.swap(map2);
print_Map("map1 swap after", map1);
print_Map("map2 swap after", map2);
cout << "swapTest() endl" << endl;
}
int main()
{
// constructorTest();
// elementAccessTest();
// capacityTest();
// iteratorTest();
// clearTest();
// insertTest();
// emplaceTest();
// eraseTest();
swapTest();
return 0;
}