C++/C++11中头文件iterator的使用
<iterator>是C++標準程序庫中的一個頭文件,定義了C++ STL標準中的一些迭代器模板類,這些類都是以std::iterator為基類派生出來的。迭代器提供對集合(容器)元素的操作能力。迭代器提供的基本操作就是訪問和遍歷。迭代器模擬了C++中的指針,可以有++運算,用*(解引用算符,deference)或->算符來訪問容器中的元素。容器中元素如果改變了所用內存,也不影響綁定的迭代器指向正確的位置。因此,迭代器實際上更像是句柄(handler)。迭代器允許C++程序以統一的方式處理不同的數據結構。迭代器充當容器和通用算法之間的中介。而不是對特定數據類型進行操作,算法被定義為在一個迭代器類型指定的范圍內運行。任何滿足迭代器要求的數據結構都可以通過算法進行操作。
STL的迭代器實現了設計模式中的”迭代器模式”,即順序訪問一個聚合中的元素,又不暴露聚合的實現細節。
迭代器支持以不同方法遍歷聚合類型。例如,對一顆樹數據類型,可以有前序、中序、后序遍歷的迭代器。同一個聚合類型的對象上,可以同時有多個迭代器,各自保持不同的遍歷狀態。在不同的聚合類型上實現的迭代器具有標準的對外接口,這給STL中的算法使用迭代器提供了可能。
一共支持五種迭代器:輸入迭代器(*iter解引用后只能用作右值)、輸出迭代器(*iter解引用后只能用作左值)、前向迭代器(具有輸入迭代器、輸出迭代器的所有功能,且可以反復遍歷操作,支持對同一個元素的多次讀寫)、雙向迭代器(是在前向迭代器的基礎上,多了單步向后遍歷的能力)、隨機訪問迭代器(在雙向迭代器基礎上,具有直接訪問各數據元素的能力。隨機迭代器增加了”迭代器算術運算”)。
std::input_iterator_tag:空類,標識一個迭代器的類別為輸入迭代器。
std::output_iterator_tag:空類,標識一個迭代器的類別為輸出迭代器。
std::forward_iterator_tag:空類,標識一個迭代器的類別為前向迭代器。
std::bidirectional_iterator_tag:空類,標識一個迭代器的類別為雙向迭代器。
std::random_access_iterator_tag:空類,標識一個迭代器的類別為隨機迭代器。
下面是從其它文章中copy的<iterator>測試代碼,詳細內容介紹可以參考對應的reference:
?
#include "iterator.hpp"
#include <iterator>
#include <iostream>
#include <typeinfo>
#include <list>
#include <vector>
#include <algorithm>
#include <deque>
#include <string>// reference: http://www.cplusplus.com/reference/iterator/namespace iterator_ {
///
class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
public:MyIterator(int* x) :p(x) {}MyIterator(const MyIterator& mit) : p(mit.p) {}MyIterator& operator++() { ++p; return *this; }MyIterator operator++(int) { MyIterator tmp(*this); operator++(); return tmp; }bool operator==(const MyIterator& rhs) const { return p == rhs.p; }bool operator!=(const MyIterator& rhs) const { return p != rhs.p; }int& operator*() { return *p; }
private:int* p;
};int test_iterator_1()
{// std::iterator: 迭代器基類int numbers[] = { 10, 20, 30, 40, 50 };MyIterator from(numbers);MyIterator until(numbers + 5);for (MyIterator it = from; it != until; it++)std::cout << *it << ' ';std::cout << '\n';return 0;
}/
int test_iterator_2()
{// std::iterator_traits: 定義迭代器屬性typedef std::iterator_traits<int*> traits;if (typeid(traits::iterator_category) == typeid(std::random_access_iterator_tag))std::cout << "int* is a random-access iterator" << std::endl;;return 0;
}///
int test_iterator_3()
{// std::advance: 將迭代器推進到n個元素位置,可以是負值std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::list<int>::iterator it = mylist.begin();std::advance(it, 5);std::cout << "The sixth element in mylist is: " << *it << '\n'; // 50return 0;
}int test_iterator_4()
{// std::back_inserter: 構造一個在x的末尾插入新元素的后插入迭代器std::vector<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::copy(bar.begin(), bar.end(), std::back_inserter(foo));std::cout << "foo contains:";for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 4 5 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_5()
{// std::begin: 返回指向序列中第一個元素的迭代器// std::end: 返回指向序列中過去的最后一個元素的迭代器int foo[] = { 10, 20, 30, 40, 50 };std::vector<int> bar;// iterate foo: inserting into barfor (auto it = std::begin(foo); it != std::end(foo); ++it)bar.push_back(*it);// iterate bar: print contents:std::cout << "bar contains:";for (auto it = std::begin(bar); it != std::end(bar); ++it)std::cout << ' ' << *it; // 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_6()
{// std::distance: 計算first和last之間的元素數量std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::list<int>::iterator first = mylist.begin();std::list<int>::iterator last = mylist.end();std::cout << "The distance is: " << std::distance(first, last) << '\n'; // 10return 0;
}int test_iterator_7()
{// std::front_inserter: 構造一個前插入迭代器,在x的開頭插入新元素std::deque<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::copy(bar.begin(), bar.end(), std::front_inserter(foo));std::cout << "foo contains:";for (std::deque<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 50 40 30 20 10 1 2 3 4 5std::cout << '\n';return 0;
}//
int test_iterator_8()
{// std::inserter: 構造一個插入迭代器,從指向的位置開始,在連續的位置中插入新元素xstd::list<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::list<int>::iterator it = foo.begin();std::advance(it, 3);std::copy(bar.begin(), bar.end(), std::inserter(foo, it));std::cout << "foo contains:";for (std::list<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 10 20 30 40 50 4 5std::cout << '\n';return 0;
}int test_iterator_9()
{// std::make_move_iterator: 從it構造一個move_iterator對象std::vector<std::string> foo(3);std::vector<std::string> bar{ "one", "two", "three" };std::copy(std::make_move_iterator(bar.begin()), std::make_move_iterator(bar.end()), foo.begin());// bar now contains unspecified values; clear it:bar.clear();std::cout << "foo:";for (std::string& x : foo) std::cout << ' ' << x; // one two threestd::cout << '\n';return 0;
}//
int test_iterator_10()
{// std::next: 獲取下一個元素的迭代器std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::cout << "mylist:";std::for_each(mylist.begin(), std::next(mylist.begin(), 5), [](int x) {std::cout << ' ' << x; }); // 0 10 20 30 40 50std::cout << '\n';return 0;
}//
int test_iterator_11()
{// std::prev: 獲取前一個元素的迭代器std::list<int> mylist;for (int i = 0; i<10; i++) mylist.push_back(i * 10);std::cout << "The last element is " << *std::prev(mylist.end()) << '\n'; // 90return 0;
}int test_iterator_12()
{// std::back_insert_iterator: 在容器末尾插入元素的迭代器std::vector<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::back_insert_iterator< std::vector<int> > back_it(foo);std::copy(bar.begin(), bar.end(), back_it);std::cout << "foo:";for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 4 5 10 20 30 40 50 std::cout << '\n';return 0;
}///
int test_iterator_13()
{// std::front_insert_iterator: 在容器開頭插入元素的迭代器std::deque<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::front_insert_iterator< std::deque<int> > front_it(foo);std::copy(bar.begin(), bar.end(), front_it);std::cout << "foo:";for (std::deque<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 50 40 30 20 10 1 2 3 4 5std::cout << '\n';return 0;
}//
int test_iterator_14()
{// std::insert_iterator: 插入迭代器std::list<int> foo, bar;for (int i = 1; i <= 5; i++) {foo.push_back(i); bar.push_back(i * 10);}std::list<int>::iterator it = foo.begin();std::advance(it, 3);std::insert_iterator< std::list<int> > insert_it(foo, it);std::copy(bar.begin(), bar.end(), insert_it);std::cout << "foo:";for (std::list<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << ' ' << *it; // 1 2 3 10 20 30 40 50 4 5std::cout << '\n';return 0;
}///
int test_iterator_15()
{// std::istreambuf_iterator: 輸入流緩存迭代器std::istreambuf_iterator<char> eos; // end-of-range iteratorstd::istreambuf_iterator<char> iit(std::cin.rdbuf()); // stdin iteratorstd::string mystring;std::cout << "Please, enter your name: ";while (iit != eos && *iit != '\n') mystring += *iit++;std::cout << "Your name is " << mystring << ".\n";return 0;
}///
int test_iterator_16()
{// std::istream_iterator: 從輸入流讀取連續元素的輸入迭代器double value1, value2;std::cout << "Please, insert two values: ";std::istream_iterator<double> eos; // end-of-stream iteratorstd::istream_iterator<double> iit(std::cin); // stdin iteratorif (iit != eos) value1 = *iit;++iit;if (iit != eos) value2 = *iit;std::cout << value1 << "*" << value2 << "=" << (value1*value2) << '\n';return 0;
}///
int test_iterator_17()
{// std::move_iterator: 用于解引用(Dereference)到一個右值引用(Rvalue reference)的迭代器std::vector<std::string> foo(3);std::vector<std::string> bar{ "one", "two", "three" };typedef std::vector<std::string>::iterator Iter;std::copy(std::move_iterator<Iter>(bar.begin()), std::move_iterator<Iter>(bar.end()), foo.begin());// bar now contains unspecified values; clear it:bar.clear();std::cout << "foo:";for (std::string& x : foo) std::cout << ' ' << x; // one two threestd::cout << '\n';return 0;
}///
int test_iterator_18()
{// std::ostreambuf_iterator: 輸出流緩存迭代器std::string mystring("Some text here...\n");std::ostreambuf_iterator<char> out_it(std::cout); // stdout iteratorstd::copy(mystring.begin(), mystring.end(), out_it); // Some text here...return 0;
}/
int test_iterator_19()
{// std::ostream_iterator: 順序寫入輸出流的輸出迭代器std::vector<int> myvector;for (int i = 1; i<10; ++i) myvector.push_back(i * 10);std::ostream_iterator<int> out_it(std::cout, ", ");std::copy(myvector.begin(), myvector.end(), out_it); // 10, 20, 30, 40, 50, 60, 70, 80, 90, return 0;
}///
int test_iterator_20()
{// std::reverse_iterator: 反向迭代器std::vector<int> myvector;for (int i = 0; i<10; i++) myvector.push_back(i);typedef std::vector<int>::iterator iter_type;// ? 0 1 2 3 4 5 6 7 8 9 ?iter_type from(myvector.begin()); // ^// ------>iter_type until(myvector.end()); // ^//std::reverse_iterator<iter_type> rev_until(from); // ^// <------std::reverse_iterator<iter_type> rev_from(until); // ^std::cout << "myvector:";while (rev_from != rev_until)std::cout << ' ' << *rev_from++; // 9 8 7 6 5 4 3 2 1 0std::cout << '\n';return 0;
}} // namespace iterator_
GitHub:https://github.com/fengbingchun/Messy_Test
?
總結
以上是生活随笔為你收集整理的C++/C++11中头文件iterator的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习中的验证集和超参数简介
- 下一篇: C++/C++11中头文件functio