天天看點

c++11 标準模闆(STL)(std::multimap)(七)修改器

定義于頭檔案 <map>      

template<

    class Key,

    class T,

    class Compare = std::less<Key>,

    class Allocator = std::allocator<std::pair<const Key, T> >

> class multimap;

(1)

namespace pmr {

    template <class Key, class T, class Compare = std::less<Key>>

    using multimap = std::multimap<Key, T, Compare,

                                  std::pmr::polymorphic_allocator<std::pair<const Key,T>>>;

}

(2) (C++17 起)

 multimap 是關聯容器,含有關鍵-值 pair 的已排序清單,同時容許多個入口擁有同一關鍵。按照應用到關鍵的比較函數

Compare

排序。搜尋、插入和移除操作擁有對數複雜度。

擁有等價關鍵的關鍵-值 pair 的順序就是插入順序,且不會更改。(C++11 起)

凡在标準庫使用比較 (Compare) 概念出,都用描述于比較 (Compare) 上的等價關系确定等價性。不精确地說,若二個對象

a

b

互不小于對方:

!comp(a, b) && !comp(b, a)

,則認為它們等價。

修改器

清除内容

std::multimap<Key,T,Compare,Allocator>::clear
           
void clear(); (C++11 前)
void clear() noexcept; (C++11 起)

從容器擦除所有元素。此調用後 size() 傳回零。

非法化任何指代所含元素的引用、指針或疊代器。任何尾後疊代器保持合法。

參數

(無)

傳回值

(無)

複雜度

與容器大小,即元素數成線性。

原位構造元素

std::multimap<Key,T,Compare,Allocator>::emplace
           

template< class... Args >

iterator emplace( Args&&... args );

(C++11 起)

 插入以給定的

args

原位構造的新元素到容器。

細心地使用

emplace

允許在構造新元素的同時避免不必要的複制或移動操作。 準确地以與提供給

emplace

者相同的參數,通過 std::forward<Args>(args)... 轉發調用新元素(即 std::pair<const Key, T> )的構造函數。

沒有疊代器或引用被非法化。

參數

args - 要轉發給元素構造函數的參數

傳回值

指向被插入元素的疊代器。

異常

若任何操作抛出異常,則此函數無效果。

複雜度

與容器大小成對數。

使用提示原位構造元素

std::multimap<Key,T,Compare,Allocator>::emplace_hint
           

template <class... Args>

iterator emplace_hint( const_iterator hint, Args&&... args );

(C++11 起)

插入新元素到盡可能接近恰在

hint

前的呆滞。原位構造元素,即不進行複制或移動操作。

準确地以與提供給函數的參數相同者,以 std::forward<Args>(args)... 轉發調用元素類型(

value_type

即 std::pair<const Key, T> )的構造函數。

沒有疊代器或引用被非法化。

參數

hint - 指向将插入新元素到其前的位置的疊代器
args - 轉發給元素構造函數的參數

傳回值

傳回指向新插入元素的疊代器。

複雜度

若任何操作抛出異常,則此函數無效果(強異常保證)。

複雜度

通常與容器大小成對數,但若正好在

hint

前插入新元素則為均攤常數。

擦除元素

std::multimap<Key,T,Compare,Allocator>::erase
           
void erase( iterator pos ); (1) (C++11 前)
iterator erase( const_iterator pos ); (C++11 起)
iterator erase( iterator pos ); (C++17 起)
void erase( iterator first, iterator last ); (2) (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

對象所抛的異常

複雜度

給定

multimap

的執行個體

c

1) 均攤常數

2) log(c.size()) + std::distance(first, last)

3) log(c.size()) + c.count(k)

交換内容

std::multimap<Key,T,Compare,Allocator>::swap
           
void swap( multimap& other ); (C++17 前)
void swap( multimap& other ) noexcept(); (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 起)

複雜度

常數。

調用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <map>
#include <time.h>

using namespace std;

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }


    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator >(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y > cell.y;
        }
        else
        {
            return x > cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

struct myCompare
{
    bool operator()(const int &a, const int &b)
    {
        return a < b;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

std::ostream &operator<<(std::ostream &os, const std::pair<const int, Cell> &pCell)
{
    os << pCell.first << "-" << pCell.second;
    return os;
}

int main()
{
    std::cout << std::boolalpha;

    std::mt19937 g{std::random_device{}()};
    srand((unsigned)time(NULL));

    auto genKey = []()
    {
        return std::rand() % 10 + 100;
    };

    auto generate = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    std::multimap<int, Cell> multimap1;
    for (size_t index = 0; index < 5; index++)
    {
        //插入以給定的 args 原位構造的新元素到容器。
        multimap1.emplace(genKey(), generate());
        std::cout << "multimap1:    ";
        std::copy(multimap1.begin(), multimap1.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
        std::cout << std::endl;
    }
    std::cout << std::endl;

    std::multimap<int, Cell> multimap2;
    for (size_t index = 0; index < 5; index++)
    {
        //插入新元素到盡可能接近恰在 hint 前的呆滞。原位構造元素,即不進行複制或移動操作。
        multimap2.emplace_hint(multimap2.begin(), genKey(), generate());
        std::cout << "multimap2:    ";
        std::copy(multimap2.begin(), multimap2.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
        std::cout << std::endl;
    }
    std::cout << std::endl;

    std::cout << "after swap" << std::endl;
    //将内容與 other 的交換。不在單個元素上調用任何移動、複制或交換操作。
    multimap1.swap(multimap2);
    std::cout << "multimap1:    ";
    std::copy(multimap1.begin(), multimap1.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;

    std::cout << "multimap2:    ";
    std::copy(multimap2.begin(), multimap2.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;


    //從容器擦除所有元素。此調用後 size() 傳回零。
    multimap1.clear();
    std::cout << "multimap1 is empty:   " << multimap1.empty() << std::endl;
    multimap2.clear();
    std::cout << "multimap2 is empty:   " << multimap2.empty() << std::endl;
    std::cout << std::endl;


    std::multimap<int, Cell> multimap3({{genKey(), generate()}, {genKey(), generate()},
        {genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    //從容器移除指定的元素。1) 移除位于 pos 的元素。
    std::cout << "multimap3:    ";
    std::copy(multimap3.begin(), multimap3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    multimap3.erase(multimap3.begin());
    std::cout << "multimap3:    ";
    std::copy(multimap3.begin(), multimap3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;

    //從容器移除指定的元素。2) 移除範圍 [first; last) 中的元素,它必須是 *this 中的合法範圍。
    std::multimap<int, Cell>::iterator bit = multimap3.begin();
    std::advance(bit, 1);
    std::multimap<int, Cell>::iterator ait = bit;
    std::advance(ait, 2);
    multimap3.erase(bit, ait);
    std::cout << "multimap3:    ";
    std::copy(multimap3.begin(), multimap3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;


    multimap3.insert({{genKey(), generate()}, {genKey(), generate()}, {genKey(), generate()}});
    //從容器移除指定的元素。3) 移除關鍵等于 key 的所有元素。
    std::cout << "multimap3:    ";
    std::copy(multimap3.begin(), multimap3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    bit = multimap3.begin();
    std::advance(bit, 3);
    multimap3.erase(bit->first);
    std::cout << "multimap3:    ";
    std::copy(multimap3.begin(), multimap3.end(), std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}
           

輸出

繼續閱讀