c++ 11标准模板(STL) std::map(二)旧

迭代器

返回指向容器第一个元素的迭代器

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-

用作搜索开始位置的建议的迭代器

(C++11 前)

指向将插入新元素到其前的位置的迭代器

(C++11 起)
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 ,则用非成员 swap 的非限定调用交换分配器。否则,不交换它们(且若 get_allocator() != other.get_allocator() ,则行为未定义)。

(C++11 起)

参数

other-要与之交换内容的容器

返回值

(无)

异常

任何 Compare 对象交换所抛的异常。

(C++17 前)
noexcept 规定:  

noexcept(std::allocator_traits<Allocator>::is_always_equal::value
&& std::is_nothrow_swappable<Compare>::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;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值