間接迭代器

Author: David Abrahams, Jeremy Siek, Thomas Witt
Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
Organization: Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction
Date: 2006-09-11
Copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
概要: indirect_iterator 改編一個迭代器,改編的方法是在 operator*() 中多使用一次提領。例如,該迭代器適配器可以用於察看一個指針容器(如 list<foo*>),就像它是一個所指類型的容器(如 list<foo>)一樣。indirect_iterator 依賴於兩個輔助 traits, pointeeindirect_reference, 它們提供了對於那些 value_type 不是一個迭代器的底層迭代器的支持。

目錄

indirect_iterator 概要

template <
class Iterator
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class indirect_iterator
{
public:
typedef /* 見下文 */ value_type;
typedef /* 見下文 */ reference;
typedef /* 見下文 */ pointer;
typedef /* 見下文 */ difference_type;
typedef /* 見下文 */ iterator_category;

indirect_iterator();
indirect_iterator(Iterator x);

template <
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);

Iterator const& base() const;
reference operator*() const;
indirect_iterator& operator++();
indirect_iterator& operator--();
private:
Iterator m_iterator; // exposition
};

indirect_iterator 的成員類型按以下偽代碼定義,其中 Viterator_traits<Iterator>::value_type

if (Value 是 use_default) then
typedef remove_const<pointee<V>::type>::type value_type;
else
typedef remove_const<Value>::type value_type;

if (Reference 是 use_default) then
if (Value 是 use_default) then
typedef indirect_reference<V>::type reference;
else
typedef Value& reference;
else
typedef Reference reference;

if (Value 是 use_default) then
typedef pointee<V>::type* pointer;
else
typedef Value* pointer;

if (Difference 是 use_default)
typedef iterator_traits<Iterator>::difference_type difference_type;
else
typedef Difference difference_type;

if (CategoryOrTraversal 是 use_default)
typedef iterator-category (
iterator_traversal<Iterator>::type,``reference``,``value_type``
) iterator_category;
else
typedef iterator-category (
CategoryOrTraversal,``reference``,``value_type``
) iterator_category;

indirect_iterator 的要求

表達式 *v 應是有效表達式且可轉換為 reference,其中 viterator_traits<Iterator>::value_type 的對象。Iterator 應符合 iterator_category 所表示的遍歷概念。Value, Reference, 和 Difference 的選擇應使得 value_type, reference, 和 difference_type 滿足 iterator_category 的要求。

[註:如果 Value 參數不是 use_default,則對於 iterator_traits<Iterator>::value_type 還有更多要求,如算法所暗示的可以推斷出 value_type 成員的缺省值。]

indirect_iterator 的模型

除了 iterator_categoryiterator_traversal<indirect_iterator>::type 所表示的概念之外,indirect_iterator 的特化類還符合以下概念,其中 viterator_traits<Iterator>::value_type 對像:

  • 可讀迭代器,如果 reference(*v) 可轉換為 value_type.
  • 可寫迭代器,如果 reference(*v) = t 是有效表達式(其中 tindirect_iterator::value_type 對像)
  • 左值迭代器,如果 reference 是引用類型。

indirect_iterator<X,V1,C1,R1,D1>indirect_iterator<Y,V2,C2,R2,D2> 可交互,當且僅當 XY 是可交互的。

indirect_iterator 的操作

除了上述概念所要求的操作以外,indirect_iterator 的特化類還提供了以下操作。

indirect_iterator();

要求: Iterator 必須是可缺省構造的。
作用: 構造一個 indirect_iterator 實例,帶有一個缺省構造的 m_iterator.

indirect_iterator(Iterator x);

作用: 構造一個 indirect_iterator 實例,帶有一個從 x 複製構造得到的 m_iterator.
template <
class Iterator2, class Value2, unsigned Access, class Traversal
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Access, Traversal, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
要求: Iterator2 可隱式轉換為 Iterator.
作用: 構造一個 indirect_iterator 實例,其 m_iterator 子對像構造自 y.base().

Iterator const& base() const;

返回: m_iterator

reference operator*() const;

返回: **m_iterator

indirect_iterator& operator++();

作用: ++m_iterator
返回: *this

indirect_iterator& operator--();

作用: --m_iterator
返回: *this
 

例子

這個例子打印一個字符數組,它使用 indirect_iterator 通過指針數組來訪問字符數組。接著再將 indirect_iterator is used 用於 transform 算法來將字符(加一)複製到另一個數組。對數據源使用了一個常量間接迭代器,而對數據目標則使用了一個非常量間接迭代器。例子的最後部分打印原來的字符數組,但這次使用的是 make_indirect_iterator 輔助函數。

char characters[] = "abcdefg";
const int N = sizeof(characters)/sizeof(char) - 1; // 減一由於字符串結尾有一個 null 字符
char* pointers_to_chars[N];
for (int i = 0; i < N; ++i)
pointers_to_chars[i] = &characters[i];

// 使用 indirect_iterator 的例子

boost::indirect_iterator<char**, char>
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);

std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;


// 創建常量與非常量間接迭代器的例子

char mutable_characters[N];
char* pointers_to_mutable_chars[N];
for (int j = 0; j < N; ++j)
pointers_to_mutable_chars[j] = &mutable_characters[j];

boost::indirect_iterator<char* const*> mutable_indirect_first(pointers_to_mutable_chars),
mutable_indirect_last(pointers_to_mutable_chars + N);
boost::indirect_iterator<char* const*, char const> const_indirect_first(pointers_to_chars),
const_indirect_last(pointers_to_chars + N);

std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));

std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;


// 使用 make_indirect_iterator() 的例子

std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;

輸出結果是:

a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,

這個例子的源代碼請見 這裡