現在看一下storageN模板,定義在storage.hpp檔案中:
先來個普通的:
namespace _bi{// 1template<class A1> struct storage1{ explicit storage1( A1 a1 ): a1_( a1 ) {} template<class V> void accept(V & v) const { BOOST_BIND_VISIT_EACH(v, a1_, 0); } A1 a1_;};
BOOST_BIND_VISIT_EACH就是visit_each模板,前面已經介紹過了,一個Visitor模式的C++ template實現。
storage1::accept函數接受visitor function object,然後交給visit_each,visit_each函數內部調用visitor function object去使用a1_。
功能很簡單,儲存一個對象,並且提供accept方法接收觀察者並調用之。
storage1提供了兩個偏特化版本支援boost::arg<N>參數和返回boost::arg<N>的函數指標。
template<int I> struct storage1< boost::arg<I> >{ explicit storage1( boost::arg<I> ) {} template<class V> void accept(V &) const { } static boost::arg<I> a1_() { return boost::arg<I>(); }};template<int I> struct storage1< boost::arg<I> (*) () >{ explicit storage1( boost::arg<I> (*) () ) {} template<class V> void accept(V &) const { } static boost::arg<I> a1_() { return boost::arg<I>(); }};
這兩個偏特化模板都提供了accept的空實現,所以不要使用它們。
建構函式也沒有儲存boost::arg<N>對象,甚至都沒有a1_成員變數。
特別提供了a1_()靜態成員函數用來直接返回boost::arg<I>()
storage2的模板類是從storage1的模板類繼承(都不是偏特化版本)
template<class A1, class A2> struct storage2: public storage1<A1>{ typedef storage1<A1> inherited; storage2( A1 a1, A2 a2 ): storage1<A1>( a1 ), a2_( a2 ) {} template<class V> void accept(V & v) const { inherited::accept(v); BOOST_BIND_VISIT_EACH(v, a2_, 0); } A2 a2_;};
因此storage2有兩個成員變數a1_和a2_.
再看看偏特化版本:
template<class A1, int I> struct storage2< A1, boost::arg<I> >: public storage1<A1>{ typedef storage1<A1> inherited; storage2( A1 a1, boost::arg<I> ): storage1<A1>( a1 ) {} template<class V> void accept(V & v) const { inherited::accept(v); } static boost::arg<I> a2_() { return boost::arg<I>(); }};template<class A1, int I> struct storage2< A1, boost::arg<I> (*) () >: public storage1<A1>{ typedef storage1<A1> inherited; storage2( A1 a1, boost::arg<I> (*) () ): storage1<A1>( a1 ) {} template<class V> void accept(V & v) const { inherited::accept(v); } static boost::arg<I> a2_() { return boost::arg<I>(); }};
又加了一個a2_()成員函數返回boost::arg<I>對象而已。
從此以後,一直不斷的設計storageN到stoarge9 .
原理還是很簡單的。總結:
storageN的模板提供了接受boost::arg<I>相關的偏特化版本。
N從1-9,提供了a1_()到a9_()的成員函數擷取boost::arg<1>到boost::arg<9>的預留位置對象。