定義于頭檔案 <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 ,則用非成員 的非限定調用交換配置設定器。否則,不交換它們(且若 get_allocator() != other.get_allocator() ,則行為未定義)。 | (C++11 起) |
參數
other | - | 要與之交換内容的容器 |
傳回值
(無)
異常
任何 對象交換所抛的異常。 | (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;
}