C++进阶篇一:C++ 标准模板库之容器和迭代

C++容器

容器(container)是C++中能够存储几乎任何数据类型的数据结构,分为一级容器、容器适配器以及类容器。不同的容器有一些共同的成员函数,通过迭代(在性质上与指针相似)可以实现对容器元素的操作。不同容器支持的迭代(具体来说是迭代权限)是不同的,这也决定了它们所能用于的算法是不同的(因为每种算法都有其特定支持的迭代类型)。内置数组也可以作为标准库算法的操作对象,此时它的指针就作为迭代。

以下为C++容器共有的成员函数:

  • 默认构造函数:初始化一个空容器
  • 复制构造函数:复制一个现存同类型容器
  • 移动构造函数:(C++11)将一个容器中的内容移到另一个同类型容器中
  • 析构函数:详见https://my.oschina.net/SamYjy/blog/828146
  • empty方法:判断容器是否为空
  • size方法:返回容器中现有元素个数,forward_list不能用
  • max_size方法:返回一个容器中所能融入的最大元素个数
  • operator=:用于复制容器内容。特别地,在C++11中用于移动容器内容。
  • operator<, operator<=, operator>, operator>=, operator==, operator!=:比较不同容器之间的属性
  • insert方法:向容器中插入元素
  • swap方法:交换两个容器的元素,C++11中作为一个使用移动构造函数的全局函数,用于交换同类型容器的地址。
  • begin方法:可返回iterator或const_iterator,用于指向容器的第一个元素
  • end方法:可返回iterator或const_iterator,用于指向容器最后一个元素的后一个位置
  • rbegin方法:可返回iterator或const_iterator,用于指向容器的最后一个元素
  • rend方法:可返回iterator或const_iterator,用于指向容器的第一个元素的前一个位置
  • cbegin:(C++11)返回const_iterator,用于指向容器的第一个元素
  • cend, crbegin和crend则可以以此类推
  • erase:从容器中删除一个或多个元素
  • clear:删除容器中所有元素(对array不适用)

C++容器共有函数使用注意点:

  1. <, <=, >, >=, ==和!=不能用于优先队列
  2. <, <=, >和 >=不能用于非顺序关联型容器(后面会详细解释)
  3. rbegin, rend, crbegin和crend不能用于forward_list

各类型容器简介如下:

一级容器:

一级容器分为序列型容器、顺序关联型容器和非顺序关联型容器。

  • 序列型容器:vector,deque, list, forward_list(为单链表,C++11新特性), array
  • 顺序关联型容器(容器中的key是排序好的):set和map(不允许重复key,此外在C++11中key是不可修改的), multiset和multimap(允许重复的key,此外在C++11中key是不可修改的)。这些头文件分别是<set>和<map>
  • 非顺序关联型容器(因为容器中的key未排序,所以性能方面可能更出色):unsorted_set, unsorted_map, unsorted_multiset和unsorted_multimap,用法与对应的顺序关联型容器类似。

在具体的算法实现方面,如果需要在容器最后进行频繁插入删除操作的话,则vector是一个理想的选择(因为vector为连续存储结构);如果需要频繁在两头进行插入删除操作,则deque是一个理想选择;如果需要在任意位置进行插入或删除操作,则list是一个理想选择。 **容器适配器:**栈、队列和优先队列 **类容器:**内置数组、比特集合(bitsets,用于对于标志集合(即flag values)和数值数组进行快速数学向量运算时使用)

C++各容器特有常用函数归纳:

序列型容器:
  • assign(n, val):将容器中的元素改为出现n次的val值。
  • assign(iters_begin, iters_end):将元素中的元素改为从begin到end的一个序列。
vector 容器(使用见例2和例3)
  • push_back(val):在vector末尾添加一个val元素
  • size:返回vector中元素的个数
  • capacity: 返回vector中能够存储的最多元素的个数
  • shift_to_fit:使得capacity与size相同,但是视编译环境不同,此指令可能被忽略。
  • at(index): 读写相应index的元素,对index范围作出检查。
  • insert(iter_index, ele):在用迭代(以begin()或cbegin()作为0加index)计算出来的index处插入ele。
  • insert(iter_insert_index, iter_start_range, iter_end_range):在被插入元素的(用迭代表示的)insert_index处插入(用迭代表示的)从start_range到end_range的一个系列。
  • erase(iter_index):删除迭代表示的index处相应元素。
  • erase(iter_begin, iter_end):删除用迭代表示的从begin到end的元素。
  • front:返回指向第一个元素的地址。
  • back:返回最后一个元素的地址。
list 容器(使用见例4)
  • push_front(ele):在list前端增加元素ele,此方法仅适用于forward_list, list和queue。
  • push_back(ele):类似vector的同名函数
  • sort:注意此处的sort与STL的sort是不同的,list特有的sort无传入参数并且默认对list中的元素按非降序排序。
  • reverse():将列表中的元素倒置。
  • splice(iter_insert_index, list& b):将list b插入本list由iterator指定的下标处并将其中所有元素删除。
  • splice(iter_insert_index, list& b, iter_delete_index):从list b中删除由迭代delete_index确定的那一个元素,并将list b中所有元素插入insert_index后删除list b中的所有元素。
  • splice(iter_insert_index, list& b, iter_start_delete_index, iter_end_delete_index):从list b中删除由迭代start_delete到end_delete中的一个范围内的元素,并将list b中所有元素插入insert_index后删除list b中的所有元素。
  • merge(list &b):(前提是本列表和列表b都已经排好序)将list b元素merge到本列表中,默认为升序排列。
  • unique():删除列表中重复的元素,每个元素仅出现一次。
  • swap(list &b):将本列表与b列表的所有元素对换。
  • remove(ele):从list中删去ele元素。
  • remove_if(未完待续)
deque 容器

与所有的vector操作基本类似,又增加了push_front和pop_front方法。

关联型容器:
  • find(x):在容器中寻找x元素并返回x元素位置的迭代。若未找到x,则返回end()位置的迭代。
multiset< T, compareObj >: (使用见例5),T为元素类型,compareObj为比较方式,一般情况下为less<T>
  • count(val):统计元素val在multiset中出现的次数
  • insert(val):将元素val插入multiset
  • insert(iter_index, val):将元素val插入iter_index
  • insert(a.iter_start(), a.iter_end()):将a容器一定范围内的值插入multiset,注意iter_start和iter_end表示反应容器元素下标的迭代
  • lower_bound(x):返回该元素最早出现的位置下标的迭代。若不存在该元素返回end位置的迭代。
  • upper_bound(x):返回该元素最晚出现的位置下标的迭代。若不存在该元素返回end位置的迭代。
  • equal_range(x):返回包含lower_bound和upper_bound两个迭代的一对元素对象(pair object),一般被赋值给自动类型的变量(如auto p)。分别用p.first和p.second两个常量获得。在去指针化时要注意这两个指针没有指向end()或rbegin()以及类似实际不存在元素的位置。
set: 与multiset一样,除了插入重复key时操作会被忽略。
multimap<T1, T2, compareObj>:(使用见例6)此处compareObj针对的是key。multimap建立了从键到值的多对一关系。

特别地,在C++11中,一个多重映射的初始化可以写成例如如下的形式:

multimap<int, double, less<int> > mMaps = 
 { {10, 22.2}, {20, 9.345}, {5, 77.4} };
  • make_pairs:一般使用方式为mMap.insert(make_pair(key, val)); 用于向multimap中插入键值对。
  • insert(pairObj):像multimap中插入一个组对象。
  • insert({key, val}):以列表初始化的方式插入键值对。
  • pair.first:取得某个键值对的键。
  • pair.second:取得某个键值对的值。
  • count(key):统计key这个键在multimap中出现的次数。
map:在C++中用来表示严格的一对一映射。

在multimap的基础上多了用下标读取的功能。如pairs[25]表示读取map pairs中键为25的值。

容器适配器:
栈(头文件<stack>):C++中,栈可用vector, list或者deque实现(默认为deque实现)。举例如下:
stack<int> intDequeStack; //Stack with underlying deque.
stack<int, vector<int> > intVStack; //Stack with underlying vector
stack<int, list<int> > intListStack; //Stack with underlying list
  • push(x):将x元素入栈
  • pop():将栈顶元素出栈
  • top():返回栈最顶端元素,不推出
队列(头文件<queue>):同样,队列也可以由vector, list或者deque实现(默认为deque实现)。常用方法如下:
  • push(x):将元素x插入队尾。
  • front():获取队列头元素的地址(不推出)
  • back():获取队列尾元素的地址(不推出)
  • pop():将队列头元素出队
优先队列:包含功能与队列完全一致,只是自动将最大的元素通过调堆放在队头。算法上的实现方式为堆(heap)。可以通过声明comparator改变推出顺序。
类容器:
bitset:编译时尺寸固定的一种用来操作比特集合的容器。定义容器示例:
//Size is an unsigned integer:
bitset<size> b;
  • set(index):将index处的比特值设为on
  • reset(index):将index处的比特值设为off
  • flip:将所有位倒置
  • index:获得所在为的地址,不作下标检查
  • at(index):获得所在为的地址,作下标检查
  • test(index):作下标检查,返回所在位的下标的布尔值。on为true,off为false
  • count:返回比特集合中下标on的位数
  • any:若比特集合中有位是on,则返回true
  • all:若比特集合中所有位都是on,则返回true
  • none:若比特集合中所有位都是off,则返回true == / !=:比较两个比特集合是否相等 &= / != / ^=/ |= / >>= (右移)/ <<=(左移):进行比特集合运算 to_string / to_ulong():分别返回比特集合的string和无符号长整数

C++迭代器

C++的迭代用于指向一级容器、序列或范围(sequences or ranges,比如输入流和输出流),适用前面提到的begin和end方法。其中,迭代器的权限从高到低分为任意存取(random access)、双向迭代(bidiretional)、单向迭代(forward)以及输入输出流(input和output,属于同级别)。其中,高级权限的迭代器拥有本级别以及所有低于其级别的迭代权限。

各个迭代权限所对应的操作如下(从高级别权限到低级别权限):

  1. 随机存取级别:p += i, p -= i, p + i, i + p, p - i, p[i](从p所指位置开始存取对应第加i个位置操作), p - p1(p和p1的距离之差), p < p1(p的位置是否在p1之前), p <= p1, p > p1以及p >= p1
  2. 双向迭代:--p, p--
  3. 向前迭代:提供所有输入和输出级别的操作
  4. 输出迭代:*p, p1 = p2
  5. 输入迭代:*p, p->m(通过迭代读取元素m), p1 == p2, p1 != p2
  6. 所有级别:++p, p++, p1 = p2 (将迭代p2赋给迭代p1)

注意:++操作对于反向迭代对象(reverse_iterator和const_reverse_iterator)来说是指向当前元素的前一个元素。

前文提到,不同的一级容器所对应的迭代权限是不同的,各一级容器的迭代权限如下:

  1. 随机存取级别:vector, array, deque
  2. 双向迭代级别:list, 顺序关联型容器、非顺序关联型容器
  3. 向前迭代级别:forward_list

C++标准模版容器常用异常

  • out_of_range:提示下标越界,例如常与at方法结合使用。
  • invalid_argument:提示函数被传入无效参量。
  • length_error:提示被创建容器中元素过多。
  • bad_alloc:提示内存不足,使用new函数创建内存时失败。

以下为若干C++ 标准模版库使用的例子:

例1:使用输入流读取两个整数进行相加:

// Fig. 15.4: fig15_04.cpp
// Demonstrating input and output with iterators.
#include <iostream>
#include <iterator> // ostream_iterator and istream_iterator
using namespace std;

int main()
{
   cout << "Enter two integers: ";

   // create istream_iterator for reading int values from cin
   istream_iterator< int > inputInt( cin );

   int number1 = *inputInt; // read int from standard input
   ++inputInt; // move iterator to next input value
   int number2 = *inputInt; // read int from standard input

   // create ostream_iterator for writing int values to cout
   ostream_iterator< int > outputInt( cout );

   cout << "The sum is: ";
   *outputInt = number1 + number2; // output result to cout
   cout << endl;
} // end main

输入图片说明

本例中,ostream_iterator<int>为只输出int类型(或其兼容类型)的输出流,它的头文件是<iterator>

例2: vector扩展、获取容量以及元素数量、迭代器使用若干操作

// Fig. 15.10: Fig15_10.cpp
// Demonstrating Standard Library vector class template.
#include <iostream>
#include <vector> // vector class-template definition
using namespace std;

// prototype for function template printVector
template < typename T > void printVector( const vector< T > &integers2 );

int main()
{
   const size_t SIZE = 6; // define array size
   int values[ SIZE ] = { 1, 2, 3, 4, 5, 6 }; // initialize values
   //vector< int > integers(4); // create vector of ints
   vector<int> integers;
   
   cout << "The initial size of integers is: " << integers.size()
      << "\nThe initial capacity of integers is: " << integers.capacity();

   // function push_back is in vector, deque and list
   for(int i = 0; i < (sizeof(values) / sizeof(int)) ; i++)
       integers.push_back(values[i]);
   
   //Size is 7 and capacity becomes 8 in this case.
   cout << "\nThe size of integers is: " << integers.size()
      << "\nThe capacity of integers is: " << integers.capacity();
   
      //Cause the vector to be cleaned up: integers.resize(4);
   integers.shrink_to_fit();
   cout << "\nThe size of integers is: " << integers.size()
      << "\nThe capacity of integers is: " << integers.capacity();
   
   cout << "\n\nOutput built-in array using pointer notation: ";
   // display values using pointer notation
   for ( const int *ptr = begin( values ); ptr != end( values ); ++ptr )
      cout << *ptr << ' ';
   
   cout << endl;
   cout << "Output vector using ptr notation: ";
   
   for(auto ptr = begin(integers); ptr != integers.end(); ptr++)
       cout << *ptr << ' ';

   cout << "\nOutput vector using iterator notation: ";
   printVector( integers );
   cout << "\nReversed contents of vector integers: ";

   // display vector in reverse order using const_reverse_iterator
   for ( auto reverseIterator = integers.crbegin();               
      reverseIterator!= integers.crend(); ++reverseIterator )
      cout << *reverseIterator << ' ';       

   cout << endl;
} // end main

// function template for outputting vector elements
template < typename T > void printVector( const vector< T > &integers2 )
{
   // display vector elements using const_iterator
   for ( auto constIterator = integers2.cbegin(); 
      constIterator != integers2.cend(); ++constIterator )
      cout << *constIterator << ' ';
   
   cout << endl;
   
//   //Can also be following way:
//   for(auto const item : integers2)
//       cout << item << ' ';
} // end function printVector

输入图片说明

注意:capacity方法视编译器不同,效果可能不同。调用shrink_to_fit()方法(C++11中)能够使得容器的capacity和元素个数相等。

例3:Vector insert, copy, erase, clean以及异常处理

// Fig. 15.11: fig15_11.cpp
// Testing Standard Library vector class template 
// element-manipulation functions.
#include <iostream>
#include <array> // array class-template definition
#include <vector> // vector class-template definition
#include <algorithm> // copy algorithm                  
#include <iterator> // ostream_iterator iterator
#include <stdexcept> // out_of_range exception
using namespace std;

int main()
{
//   const size_t SIZE = 6;   
//   array< int, SIZE > values = { 1, 2, 3, 4, 5, 6 };
//   vector< int > integers(values.cbegin(), values.cend());
   
    int values[] = {1, 2, 3, 4, 5, 6};
    vector<int> integers;
    integers.insert(integers.begin(), begin(values), end(values));
//    for(int i : values)
//        integers.push_back(i);
   
   ostream_iterator< int > output( cout, " " );

   cout << "Vector integers contains: ";
   copy( integers.cbegin(), integers.cend(), output );

   cout << "\nFirst element of integers: " << integers.front()
      << "\nLast element of integers: " << integers.back();

   integers[ 0 ] = 7; // set first element to 7
   integers.at( 2 ) = 10; // set element at position 2 to 10

   // insert 22 as 2nd element
   integers.insert( integers.cbegin() + 1, 22 );  

   cout << "\n\nContents of vector integers after changes: ";
   copy( integers.cbegin(), integers.cend(), output );

   // access out-of-range element
   try 
   {
      integers.at( 100 ) = 777;   
   } // end try
   catch ( out_of_range &outOfRange ) // out_of_range exception 
   {
      cout << "\n\nException: " << outOfRange.what();
   } // end catch

   // erase first element
   integers.erase( integers.cbegin() );
   cout << "\n\nVector integers after erasing first element: ";
   copy( integers.cbegin(), integers.cend(), output );

   // erase remaining elements
   integers.erase( integers.cbegin(), integers.cend() );
   cout << "\nAfter erasing all elements, vector integers " 
      << ( integers.empty() ? "is" : "is not" ) << " empty";

   //insert elements from the array values
   //integers.insert( integers.cbegin(), values.cbegin(), values.cend() );
   
   //If values is a built in type array, this sentence is:
   integers.insert(integers.cbegin(), begin(values), end(values));
   
   cout << "\n\nContents of vector integers before clear: ";
   copy( integers.cbegin(), integers.cend(), output );

   // empty integers; clear calls erase to empty a collection
   integers.clear();  
   cout << "\nAfter clear, vector integers " 
      << ( integers.empty() ? "is" : "is not" ) << " empty" << endl;
} // end main

输入图片说明

  • 此例中,copy方法(头文件<algorithm>)的三个参数分别为输入容器的起始位置、输入容器的结束位置(不包括)以及输出容器。
  • 此外,front方法和back方法分别返回第一个元素的地址以及最后一个元素的地址。注意begin方法是返回指向第一个元素的随即存储迭代,而end方法返回指向最后一个元素后一个位置的随机存储迭代。此外,调用front和end方法时必须确保容器非空,否则将会取得未定义参数。
  • 另:at方法跟用下标的区别在于at方法对于迭代越界进行检查,越界时抛出out_of_range异常。
  • insert方法:可被使用在任意类型的顺序序列(除了array和forward_list,原因是array尺寸固定,forward_list只有insert_after方法),将元素插入到特定位置(从begin到end,但不包括end)。其他版本的insert能将同一个元素插入多次或者插入一列元素。如如下代码在第二个元素的位置插入22这个值4遍:
// insert 22 at 2nd element 4 times
integers.insert(integers.begin() + 1, 4, 22);
  • erase方法可以删除某一个或某一范围内的特定元素(除了array不能删除以及forward_list用的是erase_after之外)。注意erase方法通常删除容器相应位置的对象,但是对于动态分配的内存并没有delete内存,从而可能导致内存泄漏。对于unique_ptr来说,erase可以删除分配的内存以及销毁指针;对于shared_ptr来说,地址计数会被降低,并且在在地址计数变为0的情况下,内存也会被删除。

例4:list容器使用示例:

// Fig. 15.13: Fig15_13.cpp
// Standard library list class template.
#include <iostream>
#include <array>
#include <list> // list class-template definition
#include <algorithm> // copy algorithm
#include <iterator> // ostream_iterator
using namespace std;

// prototype for function template printList
template < typename T > void printList( const list< T > &listRef );

int main()
{ 
   const size_t SIZE = 4;
   array< int, SIZE > ints = { 2, 6, 4, 8 };
   list< int > values; // create list of ints
   list< int > otherValues; // create list of ints

   // insert items in values
   values.push_front( 1 );
   values.push_front( 2 );
   values.push_back( 4 );
   values.push_back( 3 );
   
   cout << "values contains: ";
   printList( values );

   values.sort(); // sort values
   cout << "\nvalues after sorting contains: ";
   printList( values );
  
   // insert elements of ints into otherValues                   
   otherValues.insert( otherValues.cbegin(), ints.cbegin(), ints.cend() );
   cout << "\nAfter insert, otherValues contains: ";
   printList( otherValues );

   // remove otherValues elements and insert at end of values
   values.splice( values.cend(), otherValues );
   cout << "\nAfter splice, values contains: ";
   printList( values );

   values.sort(); // sort values
   cout << "\nAfter sort, values contains: ";
   printList( values );

   // insert elements of ints into otherValues
   otherValues.insert( otherValues.cbegin(), ints.cbegin(), ints.cend() );
   otherValues.sort(); // sort the list
   cout << "\nAfter insert and sort, otherValues contains: ";
   printList( otherValues );
   
   // remove otherValues elements and insert into values in sorted order
   values.merge( otherValues );                         
   cout << "\nAfter merge:\n   values contains: ";
   printList( values );
   cout << "\n   otherValues contains: ";
   printList( otherValues );

   values.pop_front(); // remove element from front
   values.pop_back(); // remove element from back
   cout << "\nAfter pop_front and pop_back:\n   values contains: ";
   printList( values );

   values.unique(); // remove duplicate elements
   cout << "\nAfter unique, values contains: ";
   printList( values );

   // swap elements of values and otherValues
   values.swap( otherValues );
   cout << "\nAfter swap:\n   values contains: ";
   printList( values );
   cout << "\n   otherValues contains: ";
   printList( otherValues );

   // replace contents of values with elements of otherValues
   values.assign( otherValues.cbegin(), otherValues.cend() );
   cout << "\nAfter assign, values contains: ";
   printList( values );

   // remove otherValues elements and insert into values in sorted order
   values.merge( otherValues ); 
   cout << "\nAfter merge, values contains: ";
   printList( values ); 
   
   values.remove( 4 ); // remove all 4s
   cout << "\nAfter remove( 4 ), values contains: ";
   values.reverse();
   printList( values );
   cout << endl;
} // end main

// printList function template definition; uses 
// ostream_iterator and copy algorithm to output list elements
template < typename T > void printList( const list< T > &listRef )
{
   if ( listRef.empty() ) // list is empty
      cout << "List is empty";
   else 
   {
      ostream_iterator< T > output( cout, " " );
      copy( listRef.begin(), listRef.end(), output );
   } // end else
} // end function printList

输入图片说明

例 5:multiset以及unordered_multiset使用示例:

// Fig. 15.15: Fig15_15.cpp
// Standard Library multiset class template
#include <iostream>
#include <array> 
#include <set> // multiset class-template definition
#include <algorithm> // copy algorithm
#include <iterator> // ostream_iterator
using namespace std;

int main()
{
   const size_t SIZE = 10;
   array< int, SIZE > a = { 7, 22, 9, 1, 18, 30, 100, 22, 85, 13 };
   //There should be a space between the right > of int and the right > of multiset
   //Otherwise compiling error may occur.
   multiset< int, less< int > > intMultiset; // multiset of ints
   ostream_iterator< int > output( cout, " " );

   cout << "There are currently " << intMultiset.count( 15 )
      << " values of 15 in the multiset\n";
   
   intMultiset.insert( 15 ); // insert 15 in intMultiset
   intMultiset.insert( 15 ); // insert 15 in intMultiset
   cout << "After inserts, there are " << intMultiset.count( 15 )
      << " values of 15 in the multiset\n\n";

   // find 15 in intMultiset; find returns iterator
   auto result = intMultiset.find( 15 );  

   if ( result != intMultiset.end() ) // if iterator not at end
      cout << "Found value 15\n"; // found search value 15
   
   // find 20 in intMultiset; find returns iterator
   result = intMultiset.find( 20 );

   if ( result == intMultiset.end() ) // will be true hence
      cout << "Did not find value 20\n"; // did not find 20

   // insert elements of array a into intMultiset
   intMultiset.insert( a.cbegin(), a.cend() ); 
   cout << "\nAfter insert, intMultiset contains:\n";
   copy( intMultiset.cbegin(), intMultiset.cend(), output );

   // determine lower and upper bound of 22 in intMultiset
   cout << "\n\nLower bound of 22: " 
      << *( intMultiset.lower_bound( 22 ) );
   cout << "\nUpper bound of 22: " << *( intMultiset.upper_bound( 22 ) );

   // use equal_range to determine lower and upper bound 
   // of 22 in intMultiset
   auto p = intMultiset.equal_range( 22 );

   cout << "\n\nequal_range of 22:" << "\n   Lower bound: " 
      << *( p.first ) << "\n   Upper bound: " << *( p.second );
   cout << endl;

   int count = 0;
   while(p.first != intMultiset.begin()){
        p.first--;
        count ++;
   }      
   
   cout << "p.first is the " << count << "th index in the set. " << endl;
   cout << endl;

   unordered_set<int> intSet;
   intSet.insert(a.begin(), a.end());
   copy( intMultiset.cbegin(), intMultiset.cend(), output );
} // end main

输入图片说明

备注:所有顺序关联型容器中的key(在set中key即元素)必须支持比较型功能函数。在比较类型的声明中(此处为less<int>),被比较的类型必须要与比较功能函数相对应(此处为operator<)。

例6 multimap使用示例

// Fig. 15.17: Fig15_17.cpp
// Standard Library multimap class template.
#include <iostream>
#include <map> // multimap class-template definition
using namespace std;

int main()
{
   multimap< int, double, less< int > > pairs; // create multimap

   cout << "There are currently " << pairs.count( 15 )
      << " pairs with key 15 in the multimap\n";

   // insert two value_type objects in pairs
   pairs.insert( make_pair( 15, 2.7 ) );
   pairs.insert( make_pair( 15, 99.3 ) );
   
   cout << "After inserts, there are " << pairs.count( 15 )
      << " pairs with key 15\n\n";
   
   auto val1 = make_pair( 30, 111.11 );
   // insert five value_type objects in pairs
   pairs.insert( val1 );
   pairs.insert({10, 22.2} );
   pairs.insert( make_pair( 25, 33.333 ) );
   pairs.insert( make_pair( 20, 9.345 ) );
   pairs.insert( make_pair( 5, 77.54 ) );
   
   cout << "Multimap pairs contains:\nKey\tValue\n";
   
   // walk through elements of pairs
   for ( auto mapItem : pairs )
      cout << mapItem.first << '\t' << mapItem.second << '\n';

   cout << endl;
} // end main

输入图片说明

参考资料:

Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版)

转载于:https://my.oschina.net/Samyan/blog/855953

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值