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