2009/06/16

複習

承下文,這樣應該是比較合理的實作:

 1: template<typename Derived>  // Curiously Recurring Template Pattern
 2: class GetSet {              // ref. <<C++ Templates: the Complete Guide>>,
 3:                             //      <<C++ Template Metaprogramming>>
 4: 
 5: protected:
 6: 
 7:   ~GetSet() { }
 8: 
 9:   template<typename T, typename C, T C::* P>
10:   class Selector {  // used for selecting which field to access
11:     friend class GetSet;
12:     static T C::* const MP;
13:     typedef T Type;
14:     ~Selector();
15:   };
16: 
17: public:
18: 
19:   template<typename S>
20:   const typename S::Type& get() const {
21:     return static_cast<const Derived* const>(this)->*S::MP;
22:   }
23:   template<typename S>
24:   void set(const typename S::Type& value){
25:     static_cast<Derived* const>(this)->*S::MP = value;
26:   }
27: 
28: };
29: 
30: template<typename Derived>
31: template<typename T, typename C, T C::* P>
32: T C::* const GetSet<Derived>::Selector<T, C, P>::MP = P;
33: 
34: // make defining selectors easier
35: #define GENERATE_SELECTOR(C,T,P,N) typedef Selector< T , C , & C :: P > N
class GetSet 的 destructor 是 protected,所以只能作為 base class 使用。class Selector 變成 class GetSet 的 protected member,所以只有 derived class 可以直接取用 class Selector,而且它的所有 members 都是 private,透過 friend class declaration 只供 class GetSet 存取,使 pointers to private members 不外洩,最後 class Selector 的 destructor 是 private(而且無定義)所以不能產生 objects。應該還可以再多寫一點讓 class GetSet 只能以 CRTP 的型式使用,不過我想已經複習夠了 XD。

--
好啦,我覺得似乎真的和 dependent types 有點親戚關係…

Labels: