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 GetSetprotected 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: