klao@976: #include klao@976: #include klao@976: klao@976: using namespace std; klao@976: using namespace boost; klao@976: klao@976: struct True { klao@976: static const bool value = true; klao@976: }; klao@976: struct False { klao@976: static const bool value = false; klao@976: }; klao@976: klao@976: // Here are some graph structures. Some of them define the type "OneTag" klao@976: // to True or False, some does not. Not defining a tag is (or at least klao@976: // should be) equivalent to defining it to "False". klao@976: struct Graph1 {}; klao@976: struct Graph2 { klao@976: typedef True OneTag; klao@976: }; klao@976: struct Graph3 { klao@976: typedef False OneTag; klao@976: }; klao@976: klao@976: klao@976: /**************** The first method to use tags ****************/ klao@976: klao@976: template klao@976: struct HasOneTag { klao@976: typedef False TheTag; klao@976: }; klao@976: klao@976: // specialization for those graphs which defined the tag to be true: klao@976: template klao@976: struct HasOneTag::type > { klao@976: typedef True TheTag; klao@976: }; klao@976: klao@976: template klao@976: int cn1(const Graph &, False) { klao@976: return 0; klao@976: } klao@976: klao@976: template klao@976: int cn1(const Graph &, True) { klao@976: return 1; klao@976: } klao@976: klao@976: template klao@976: int cn1(const Graph &g) { klao@976: return cn1(g, typename HasOneTag::TheTag()); klao@976: } klao@976: klao@976: /**************** The second method ****************/ klao@976: klao@976: // An artificial type to provoke a conversion to avoid ambuguity... klao@976: template klao@976: struct Wrap { klao@976: const T &value; klao@976: Wrap(const T &t) : value(t) {} klao@976: }; klao@976: klao@976: template klao@976: typename enable_if::type klao@976: _cn2(const Graph &) { klao@976: return 1; klao@976: } klao@976: klao@976: template klao@976: int _cn2(Wrap) { klao@976: return 0; klao@976: } klao@976: klao@976: template klao@976: int cn2(const Graph& g) { klao@976: return _cn2(g); klao@976: } klao@976: klao@976: klao@976: int main() { klao@976: Graph1 g1; klao@976: Graph2 g2; klao@976: Graph3 g3; klao@976: klao@976: cout << "The first method:\n"; klao@976: cout << "G1: " << cn1(g1) << endl; klao@976: cout << "G2: " << cn1(g2) << endl; klao@976: cout << "G3: " << cn1(g3) << endl; klao@976: klao@976: cout << "The second method:\n"; klao@976: cout << "G1: " << cn2(g1) << endl; klao@976: cout << "G2: " << cn2(g2) << endl; klao@976: cout << "G3: " << cn2(g3) << endl; klao@976: klao@976: }