| 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, pointee 和 indirect_reference, 它們提供了對於那些 value_type 不是一個迭代器的底層迭代器的支持。 |
|---|
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 的成員類型按以下偽代碼定義,其中 V 為 iterator_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;
表達式 *v 應是有效表達式且可轉換為 reference,其中 v 是 iterator_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 成員的缺省值。]
除了 iterator_category 和 iterator_traversal<indirect_iterator>::type 所表示的概念之外,indirect_iterator 的特化類還符合以下概念,其中 v 為 iterator_traits<Iterator>::value_type 對像:
- 可讀迭代器,如果 reference(*v) 可轉換為 value_type.
- 可寫迭代器,如果 reference(*v) = t 是有效表達式(其中 t 是 indirect_iterator::value_type 對像)
- 左值迭代器,如果 reference 是引用類型。
indirect_iterator<X,V1,C1,R1,D1> 與 indirect_iterator<Y,V2,C2,R2,D2> 可交互,當且僅當 X 與 Y 是可交互的。
除了上述概念所要求的操作以外,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,
這個例子的源代碼請見 這裡。