boost::iterator_rangeとboost::sub_rangeの違い

  • 戻り値にsub_rangeを使うと、一時オブジェクトによって意図しないconst性が付加されてしまう
  • iterator_rangeのconst性は、それが保持するiteratorのconst性に関与しない
  • Boost.StringAlgorithmのように、戻り値には必ずiterator_rangeを使うこと
  • sub_rangeはフロントエンドとして働く
  • iterator_range自身の寿命と、それが保持するiteratorの寿命は関係がない
    • 関数は、一時オブジェクトのiterator_rangeを受け取った場合でも、有効なiteratorを返すことができる
    • しかしboost::find_first等はなぜかconst参照のオーバーロードがない


[]#include[] []<boost/algorithm/string.hpp>[]
[]#include[] []<boost/range.hpp>[]
[]#include[] []<iostream>[]
[]#include[] []<string>[]

[]template[][]< [][]class[] []Range[][] >[]
[]boost[][]::[][]iterator_range[][]< [][]typename[] []boost[][]::[][]range_result_iterator[][]<[][]Range[][]>::[][]type[][] >[]
[]do_good[][]([][]Range[][]& [][]rng[][]);[]

[]template[][]< [][]class[] []Range[][] >[]
[]boost[][]::[][]iterator_range[][]< [][]typename[] []boost[][]::[][]range_result_iterator[][]<[][]Range[] []const[][]>::[][]type[][] >[]
[]do_good[][]([][]Range[] []const[][]& [][]rng[][]); [][]// for temporary[]

[]template[][]< [][]class[] []Range[][] >[]
[]boost[][]::[][]sub_range[][]<[][]Range[][]>[]
[]do_bad[][]([][]Range[][]& [][]rng[][]);[]

[]template[][]< [][]class[] []Range[][] >[]
[]boost[][]::[][]sub_range[][]<[][]Range[] []const[][]>[]
[]do_bad[][]([][]Range[] []const[][]& [][]rng[][]); [][]// for temporary[]

[]int[] []main[][]()[]
[]{[]

[]std[][]::[][]string[] []str[][]([][]"hello range"[][]);[]
[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[][]> [][]sr0[][] = [][]do_good[][]([][]str[][]);[]
[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[][]> [][]sr1[][] = [][]do_bad[][]([][]str[][]);[]

[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[][]> [][]sr2[][] = [][]do_good[][]([][]do_good[][]([][]str[][]));[]
[]// boost::sub_range<std::string> sr3 = do_bad(do_bad(str)); // error![]
[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[] []const[][]> [][]sr4[][] = [][]do_bad[][]([][]do_bad[][]([][]str[][]));[]

[]// boost::sub_range<std::string> sr5 = boost::find_first(boost::find_first(str, "hello"), "llo"); // oops![]
[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[][]> [][]sr6[][] = [][]boost[][]::[][]find_first[][]([][]str[][], [][]"hello"[][]);[]
[]boost[][]::[][]sub_range[][]<[][]std[][]::[][]string[][]> [][]sr7[][] = [][]boost[][]::[][]find_first[][]([][]sr6[][], [][]"llo"[][]);[]
[]return[] []0[][];[]
[]}[]