(二) boost::lambda 源码分析

由于boost::lambda用了boost::tuple。

那么对tuple关键的代码进行分析。

tuple的使用很方面,也很简单,比如:

boost::tuple<int,double,string> triple(42, 3.245, "The amazing tuple!"); 
int a0 = triple.get<0>(); 
double a1 = triple.get<1>(); 
string a2 = triple.get<2>();

 

tuple的源码如下:

// -- tuple ------------------------------------------------------
 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> class tuple : public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type {
 public: typedef typename detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
 typedef typename inherited::head_type head_type;
 typedef typename inherited::tail_type tail_type; // access_traits<T>::parameter_type takes non-reference types as const T& tuple() {} tuple(typename access_traits<T0>::parameter_type t0) : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {} 
tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1) : inherited(t0, t1, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {} tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2) : inherited(t0, t1, t2, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {} 
tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3) : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {} 
tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4) : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {}
 tuple(typename access_traits<T0>::parameter_type t0,         typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4, typename access_traits<T5>::parameter_type t5) : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(), detail::cnull(), detail::cnull()) {} 
tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4, typename access_traits<T5>::parameter_type t5, typename access_traits<T6>::parameter_type t6) : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(), detail::cnull(), detail::cnull()) {}
 tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4, typename access_traits<T5>::parameter_type t5, typename access_traits<T6>::parameter_type t6, typename access_traits<T7>::parameter_type t7) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(), detail::cnull()) {} tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4, typename access_traits<T5>::parameter_type t5, typename access_traits<T6>::parameter_type t6, typename access_traits<T7>::parameter_type t7, typename access_traits<T8>::parameter_type t8) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {} 
tuple(typename access_traits<T0>::parameter_type t0, typename access_traits<T1>::parameter_type t1, typename access_traits<T2>::parameter_type t2, typename access_traits<T3>::parameter_type t3, typename access_traits<T4>::parameter_type t4, typename access_traits<T5>::parameter_type t5, typename access_traits<T6>::parameter_type t6, typename access_traits<T7>::parameter_type t7, typename access_traits<T8>::parameter_type t8, typename access_traits<T9>::parameter_type t9) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {} template<class U1, class U2> tuple(const cons<U1, U2>& p) : inherited(p) {} 
template <class U1, class U2> tuple& operator=(const cons<U1, U2>& k) { inherited::operator=(k); return *this; 
} template <class U1, class U2> tuple& operator=(const std::pair<U1, U2>& k) { BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2 this->head = k.first; this->tail.head = k.second; return *this;
 }
 }; // The empty tuple template <> class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> : public null_type { public: typedef null_type inherited; };

 

其中tuple继承map_tuple_to_cons是这个类很关键的角色,它之所以能够存放类型和类型对应

的变量(这个类是由cons类完成的)就是因为这个原因。

而map_tuple_to_cons的实现方式也值得研究:

 

template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> struct map_tuple_to_cons { typedef cons<T0, typename map_tuple_to_cons<T1, T2, T3, T4, T5, T6, T7, T8, T9, null_type>::type > type; }; // The empty tuple is a null_type template <> struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> { typedef null_type type; };

这个类,如果用cons来描述,展开的形式如下:

cons<T0,cons<T1,cons<T2,cons<T3,cons<T4,cons<T5,cons<T6,cons<T7,cons<T8,cons<T9,null_type>>>>>>>>>>

这样的形式才能形成模板递归。在《Modern C++ Design》这本书前面的章节,有许多关于这方面的讨论。

形式上基本一样,不过tuple数据结构含有类型对应的变量。这点与书上不同的地方。

访问元素的方式同书上一样。

上面的inherited的类型是cons是一个嵌套的递归模板方式,因此构造函数的调用是调用:

template <class HT, class TT> struct cons { 
typedef HT head_type;
 typedef TT tail_type;
 typedef typename detail::wrap_non_storeable_type<head_type>::type stored_head_type; stored_head_type head; 
tail_type tail; 
typename access_traits<stored_head_type>::non_const_type get_head() { return head; } typename access_traits<tail_type>::non_const_type get_tail() { return tail; }
 typename access_traits<stored_head_type>::const_type get_head() const { return head; } typename access_traits<tail_type>::const_type get_tail() const { return tail; } cons() : head(), tail() {} // cons() : head(detail::default_arg<HT>::f()), tail() {}
// the argument for head is not strictly needed, but it prevents 
// array type elements. This is good, since array type elements
 // cannot be supported properly in any case (no assignment,
 // copy works only if the tails are exactly the same type, ...) 
cons(typename access_traits<stored_head_type>::parameter_type h, const tail_type& t) : head (h), tail(t) {} 
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10> cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 ) : head (t1), tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull()) {} 
template <class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10> cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 ) : head (), tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull()) {} template <class HT2, class TT2> cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
 template <class HT2, class TT2> cons& operator=( const cons<HT2, TT2>& u ) { head=u.head; tail=u.tail; return *this; }
 // must define assignment operator explicitly, implicit version is // illformed if HT is a reference (12.8. (12)) cons& operator=(const cons& u) { head = u.head; tail = u.tail; return *this; } template <class T1, class T2> cons& operator=( const std::pair<T1, T2>& u ) { BOOST_STATIC_ASSERT(length<cons>::value == 2);
 // check length = 2 head = u.first; tail.head = u.second; return *this; } // get member functions (non-const and const) template <int N> typename access_traits< typename element<N, cons<HT, TT> >::type >::non_const_type get() { return boost::tuples::get<N>(*this); // delegate to non-member get } template <int N> typename access_traits< typename element<N, cons<HT, TT> >::type >::const_type get() const { return boost::tuples::get<N>(*this); // delegate to non-member get } }; 
template <class HT> struct cons<HT, null_type> { typedef HT head_type;
 typedef null_type tail_type; typedef cons<HT, null_type> self_type;
 typedef typename detail::wrap_non_storeable_type<head_type>::type stored_head_type; stored_head_type head; 
typename access_traits<stored_head_type>::non_const_type get_head() { return head; } null_type get_tail() { return null_type(); }
 typename access_traits<stored_head_type>::const_type get_head() const { return head; } const null_type get_tail() const { return null_type(); } // cons() : head(detail::default_arg<HT>::f()) {} 
cons() : head() {} 
cons(typename access_traits<stored_head_type>::parameter_type h, const null_type& = null_type()) : head (h) {}
 template<class T1> cons(T1& t1, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head (t1) {} 
cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head () {} 
template <class HT2> cons( const cons<HT2, null_type>& u ) : head(u.head) {} template <class HT2> cons& operator=(const cons<HT2, null_type>& u ) { head = u.head; return *this; } // must define assignment operator explicitely, implicit version // is illformed if HT is a reference cons& operator=(const cons& u) { head = u.head; return *this; } template <int N> typename access_traits< typename element<N, self_type>::type >::non_const_type get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) { return boost::tuples::get<N>(*this); 
} 
template <int N> typename access_traits< typename element<N, self_type>::type >::const_type get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) const { return boost::tuples::get<N>(*this); 
} 
};

上面的代码特别注意构造函数的调用方式,会递归的调用的构造函数。

其它同书上代码一样。而head实际上就是存放的变量,tail是末尾类型的变量,即可能是嵌套

模板对象也可能是单个元素(类型)对象(最后)。通过递归的方式,把所有的类型及变量变得可以访问。

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yshuise

权术横行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值