traits 技法
C++语言: Codee#25861
001 #include <iostream>
002 using namespace std;
003
004 /*
005 traits 技术
006 将某种类型相关联的所有申明绑定在一起的实现方式
007 可以以灵活的方法从它们中的语境中将这些的类型和值进行“混合与匹配”
008 chm按:在stl的源码中多见此技术的使用,Hjj 先生将其视为一种重要的技术
009 */
010 class Milk
011 {
012 public:
013 friend ostream& operator<<(ostream& os, const Milk&)
014 {
015 return os << "Milk";
016 }
017 };
018
019 class CondensedMilk
020 {
021 public:
022 friend ostream&
023 operator<<(ostream& os, const CondensedMilk&)
024 {
025 return os << "Condensed Milk";
026 }
027 };
028
029 class Honey
030 {
031 public:
032 friend ostream& operator<<(ostream& os, const Honey&)
033 {
034 return os << "Honey";
035 }
036 };
037
038 class Cookies
039 {
040 public:
041 friend ostream& operator<<(ostream& os, const Cookies&)
042 {
043 return os << "Cookes";
044 }
045 };
046
047 class Bear
048 {
049 public:
050 friend ostream& operator<<(ostream& os, const Bear&)
051 {
052 return os << "Theodore";
053 }
054 };
055
056 class Boy
057 {
058 public:
059 friend ostream& operator<<(ostream& os, const Boy&)
060 {
061 return os << "Patrick";
062 }
063 };
064
065 template<class Guest>
066 class GuestTraits;
067
068 template<>
069 class GuestTraits<Bear>
070 {
071 public:
072 typedef CondensedMilk beverage_type;
073 typedef Honey snack_type;
074 };
075
076 template<> class GuestTraits<Boy>
077 {
078 public:
079 typedef Milk beverage_type;
080 typedef Cookies snack_type;
081 };
082
083 class MixedUpTraits
084 {
085 public:
086 typedef Milk beverage_type;
087 typedef Honey snack_type;
088 };
089
090 template<class Guest, class traits = GuestTraits<Guest> >
091 class BearCorner
092 {
093 Guest theGuest;
094 typedef typename traits::beverage_type beverage_type;
095 typedef typename traits::snack_type snack_type;
096 beverage_type bev;
097 snack_type snack;
098 public:
099 BearCorner(const Guest& g)
100 : theGuest(g)
101 {}
102 void entertain()
103 {
104 cout << "Entertaining " << theGuest
105 << " serving " << bev
106 << " and " << snack << endl;
107 }
108 };
109
110 int main()
111 {
112 Boy cr;
113 BearCorner<Boy> pc1(cr);
114 pc1.entertain();
115
116 Bear pb;
117 BearCorner<Bear> pc2(pb);
118 pc2.entertain();
119 BearCorner<Bear, MixedUpTraits> pc3(pb);
120 pc3.entertain();
121
122 return 0;
123 }
124 /*
125 Entertaining Patrick serving Milk and Cookes
126 Entertaining Theodore serving Condensed Milk and Honey
127 Entertaining Theodore serving Milk and Honey
128
129 Process returned 0 (0x0) execution time : 0.071 s
130 Press any key to continue.
131 */
002 using namespace std;
003
004 /*
005 traits 技术
006 将某种类型相关联的所有申明绑定在一起的实现方式
007 可以以灵活的方法从它们中的语境中将这些的类型和值进行“混合与匹配”
008 chm按:在stl的源码中多见此技术的使用,Hjj 先生将其视为一种重要的技术
009 */
010 class Milk
011 {
012 public:
013 friend ostream& operator<<(ostream& os, const Milk&)
014 {
015 return os << "Milk";
016 }
017 };
018
019 class CondensedMilk
020 {
021 public:
022 friend ostream&
023 operator<<(ostream& os, const CondensedMilk&)
024 {
025 return os << "Condensed Milk";
026 }
027 };
028
029 class Honey
030 {
031 public:
032 friend ostream& operator<<(ostream& os, const Honey&)
033 {
034 return os << "Honey";
035 }
036 };
037
038 class Cookies
039 {
040 public:
041 friend ostream& operator<<(ostream& os, const Cookies&)
042 {
043 return os << "Cookes";
044 }
045 };
046
047 class Bear
048 {
049 public:
050 friend ostream& operator<<(ostream& os, const Bear&)
051 {
052 return os << "Theodore";
053 }
054 };
055
056 class Boy
057 {
058 public:
059 friend ostream& operator<<(ostream& os, const Boy&)
060 {
061 return os << "Patrick";
062 }
063 };
064
065 template<class Guest>
066 class GuestTraits;
067
068 template<>
069 class GuestTraits<Bear>
070 {
071 public:
072 typedef CondensedMilk beverage_type;
073 typedef Honey snack_type;
074 };
075
076 template<> class GuestTraits<Boy>
077 {
078 public:
079 typedef Milk beverage_type;
080 typedef Cookies snack_type;
081 };
082
083 class MixedUpTraits
084 {
085 public:
086 typedef Milk beverage_type;
087 typedef Honey snack_type;
088 };
089
090 template<class Guest, class traits = GuestTraits<Guest> >
091 class BearCorner
092 {
093 Guest theGuest;
094 typedef typename traits::beverage_type beverage_type;
095 typedef typename traits::snack_type snack_type;
096 beverage_type bev;
097 snack_type snack;
098 public:
099 BearCorner(const Guest& g)
100 : theGuest(g)
101 {}
102 void entertain()
103 {
104 cout << "Entertaining " << theGuest
105 << " serving " << bev
106 << " and " << snack << endl;
107 }
108 };
109
110 int main()
111 {
112 Boy cr;
113 BearCorner<Boy> pc1(cr);
114 pc1.entertain();
115
116 Bear pb;
117 BearCorner<Bear> pc2(pb);
118 pc2.entertain();
119 BearCorner<Bear, MixedUpTraits> pc3(pb);
120 pc3.entertain();
121
122 return 0;
123 }
124 /*
125 Entertaining Patrick serving Milk and Cookes
126 Entertaining Theodore serving Condensed Milk and Honey
127 Entertaining Theodore serving Milk and Honey
128
129 Process returned 0 (0x0) execution time : 0.071 s
130 Press any key to continue.
131 */