複習
承下文,這樣應該是比較合理的實作:
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: Programming


<< 回到主頁