boost::iterator_adaptor (II) (轉)

worldblog發表於2007-12-13
boost::iterator_adaptor (II) (轉)[@more@]

發信人: huxw (米老鴨和唐老鼠), 信區: Programming
標  題: boost::iterator_adaptor  (II)
發信站: BBS 水木清華站 (Sun May 19 22:27:09 2002)

申明:這裡只是一種技巧。從某種眼光看來過於花哨。所以我只是介紹
介紹,並不是要鼓勵大家都這樣去折磨你的。 ;)

  II) 簡化複雜的模板引數列表

  iterator模版中用到很多模版引數, value, pointer, reference等等,
  他們之間並非沒有聯絡. 事實上, 這些模版引數的預設值本來都是推算
  出來的.

  template   class Value = typename std::iterator_traits::value_type,
  class Reference = typename iterator_defaults::reference,
  class Pointer = typename iterator_defaults::pointer,
  class Category = typename std::iterator_traits::iterator_category,
  class Distance = typename std::iterator_traits::difference_type
  >

  很合理是吧, 但是有沒有想過如果我們並不需要提供那麼多模版引數的
  時候總需要輸入那麼多, 會怎麼樣? 有沒有想過如果這樣的推算推不出
  結果來怎麼辦? 所以最後我們看到的程式碼是醬紫的.

  template   class Value = ::boost::detail::default_argument,
  class Reference = ::boost::detail::default_argument,
  class Pointer = ::boost::detail::default_argument,
  class Category = ::boost::detail::default_argument,
  class Distance = ::boost::detail::default_argument
  > struct iterator_adaptor

  這樣的程式碼能帶來什麼好處呢? 就是我們可以醬紫例項化模版了.

  iterator_adaptor  tranorm_iterator_policies,
  iterator_category_is<:input_iterator_tag>,
  value_type_is, reference_is
  > myite;

  注意到了嘛, 模版引數根本不和我們宣告的時候相同. ;) 多奇妙啊,
  我們用預設引數的時候都不能這樣.

  宣告: int foo(int i, long j = 0, double k = 9.8);
  而的時候:foo(1, k = 8.7);  // 錯誤

  但是模版例項化的時候可以. 原因就在於iterator_adaptor開始時做的
  手腳. 他用了一個iterator_traits_gen的模板. 這個模版並不在乎我
  們給的模版引數的意義, 他只是簡單的構建一個typelist, 然後利用
  find_param從typelist中把需要的型別撿出來.

  typedef detail::cons_type< typename make_arg::type,
  detail::cons_type::type,
  detail::cons_type::type,
  detail::cons_type::type,
  detail::cons_type::type,
  end_of_list> > > > > ArgList;

  typedef typename find_param::type Val;
  typedef typename find_param::type Diff;
  typedef typename find_param::type Cat;
  typedef typename find_param::type Ptr;
  typedef typename find_param::type Ref;

  結合上面的程式碼中出現的value_type_is類似的方法, 你一定直覺到make_arg
  有問題. 確實,

  template struct is_named_parameter {
  enum { value = false; }
  };

  template struct is_named_parameter > { enum { value = true }; };

  template
  struct make_arg {
  enum { is_named = is_named_parameter::value };
  //我們使is_named_parameter對value_type_is型別做特化, 那麼.... 呵呵
  typedef typename if_true::template
  then  make_key_value>::type Make;  //反之就是make_key_valye::type
  typedef typename Make::template ::type type;
  };

  struct make_named_arg {
  template
  struct select { typedef typename Value::type type; };
  };  //如果用value_type_is做模版引數
  struct make_key_value {

  struct make_named_arg {
  template
  struct select { typedef typename Value::type type; };
  };  //如果用value_type_is做模版引數
  struct make_key_value {
  template
  struct select { typedef detail::cons_type type; };
  };  //如果用T做模版引數

  是不是有了一點心得了? 那麼長的篇幅, 看到這裡真不容易. 既然都看
  到這裡了, 就幫個忙, 給peach寫一封信騷擾, 請他寫寫
  boost::function吧. ;)

 

-- 
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 


※ 修改:·huxw 於 May 19 22:28:23 修改本文·[FROM:  166.111.172.6] 
※ 來源:·BBS 水木清華站 bbs.edu.cn·[FROM: 166.111.172.6]


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992677/,如需轉載,請註明出處,否則將追究法律責任。

相關文章