属するコンテナを持たないイテレータのdereferenceについて

  • iterator_facadeはReferenceが参照型でない場合、IteratorCagegoryをInputIteratorに格下げする
    • 参照でないとForwardIteratorの規定(24.1.3/1 の最後の行)を満たせないから
    • ForwardIteratorのdereferenceは参照型でなくてはいけないから (24.1.3/1)
    • RandomAccessTraversalであるが、InputIteratorであるIteratorが出来上がったりする
    • STLはTraversalコンセプトを知らないので、おそらく非効率なアルゴリズムが選択される
  • それを避ける方法
    • iterator_facadeを黙らせる・・・u8_to_u32_iterator
      • traversalタグではなく、categoryタグを指定すると格下げされない(ただし不正)
    • Iterator自身が参照されるオブジェクトを持つ・・・token_iterator, counting_iterator
      • これも(24.1.3/1 の最後の行)を満たせないので厳密には不正なForwardIterator
    • Iteratorたちでコンテナを一個管理してしまう・・・shared_container_iterator, spirit::multi_pass
    • 無理やり参照型を返すようなiterator adaptorを作ってみる・・・ソースコード
  • *itはitの寿命が尽きると消えてしまう(かもしれない)オブジェクトへの参照を返してよい (24.1/9)
  • 同時に、*itがitより長生きしていることに依存したコードを(汎用関数には)書いてはいけない
    • itをコピーしておくか(24.4.1.3.4)、*itを値としてコピーしておく
      • 24.4.1.3.4はたぶんまだ適用されていないので注意
    • boost::reverse_iteratorは、依存している(counting_iteratorとは使えない)・・・依存しないバージョン
  • boost::iterator_category/traversalはあくまでis_convertibleな型を返すだけなのでmpl::if_などでディスパッチするときは注意

[]template[][] <[][]class[] []It[][]>[]
[]struct[] []pure_traversal[]
[] : [][]boost[][]::[][]detail[][]::[][]pure_traversal_tag[][]<[]
[]typename[] []boost[][]::[][]iterator_traversal[][]<[][]It[][]>::[][]type[]
[] >[]
[]{ };[]

[]struct[] []id[]
[]{[]
[]typedef[] []int[][]& [][]result_type[][];[]

[]int[][]& [][]operator[][]()([][]int[][]& [][]x[][])[]
[] {[]
[]return[] []x[][];[]
[] }[]
[]};[]


[]struct[] []inc[]
[]{[]
[]typedef[] []int[] []result_type[][]; [][]// non reference[]

[]int[] []operator[][]()([][]int[] []x[][])[]
[] {[]
[]return[] []x[][] + [][]1[][];[]
[] }[]
[]};[]


[]typedef[] []std[][]::[][]vector[][]<[][]int[][]> [][]rng_t[][];[]
[]typedef[] []rng_t[][]::[][]iterator[] []iter_t[][];[]


[]typedef[] []boost[][]::[][]transform_iterator[][]< ::[][]id[][], [][]iter_t[][] > [][]id_tr_iter_t[][];[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_same[][]<[]
[] ::[][]pure_traversal[][]<[][]id_tr_iter_t[][]>::[][]type[][],[]
[]boost[][]::[][]random_access_traversal_tag[]
[] > ));[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_convertible[][]<[]
[]boost[][]::[][]iterator_category[][]<[][]id_tr_iter_t[][]>::[][]type[][],[]
[]std[][]::[][]random_access_iterator_tag[]
[] > ));[]


[]typedef[] []boost[][]::[][]transform_iterator[][]< ::[][]inc[][], [][]iter_t[][] > [][]inc_tr_iter_t[][];[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_same[][]<[]
[] ::[][]pure_traversal[][]<[][]inc_tr_iter_t[][]>::[][]type[][],[]
[]boost[][]::[][]random_access_traversal_tag[]
[] > ));[]

[]BOOST_MPL_ASSERT_NOT[][](( [][]boost[][]::[][]is_convertible[][]<[]
[]boost[][]::[][]iterator_category[][]<[][]inc_tr_iter_t[][]>::[][]type[][],[]
[]std[][]::[][]forward_iterator_tag[]
[] > ));[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_convertible[][]<[]
[]boost[][]::[][]iterator_category[][]<[][]inc_tr_iter_t[][]>::[][]type[][],[]
[]std[][]::[][]input_iterator_tag[]
[] > ));[]


[]typedef[] []pstade[][]::[][]oven[][]::[][]const_lvalue_iterator[][]< [][]inc_tr_iter_t[][] > [][]lvalue_iter_t[][];[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_same[][]<[]
[] ::[][]pure_traversal[][]<[][]lvalue_iter_t[][]>::[][]type[][],[]
[]boost[][]::[][]random_access_traversal_tag[]
[] > ));[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_convertible[][]<[]
[]boost[][]::[][]iterator_category[][]<[][]lvalue_iter_t[][]>::[][]type[][],[]
[]std[][]::[][]random_access_iterator_tag[]
[] > ));[]

[]BOOST_MPL_ASSERT[][](( [][]boost[][]::[][]is_lvalue_iterator[][]<[]
[]lvalue_iter_t[]
[] > ));[]