标签:
分类: C/C++
1 template<typename T, bool C = true> 2 struct if_ { 3 static const int value = 1; 4 }; 5 6 template<typename T> 7 struct if_<T, true> { 8 static const int value = 2; 9 }; 10 11 int main() { 12 printf("value: %d\n", if_<int>::value); 13 }
上面的输入结果是: value: 2. 编译器在进行匹配的时候, 就如Prime上说的, 编译器会先创建候选函数列表, 在创建候选列表的过程中C已经被赋予默认是true, 然后在进行匹配, 最高优先级是函数, 显然这里没有. 然后是最匹配和最特化的模板函数, 所以, 就匹配到第二个函数了, 因此value等于2.
1 template<typename T, bool C = true> 2 struct if_ {}; 3 4 template<typename T> 5 struct if_<T, false> { 6 static const int value = 1; 7 }; 8 9 template<typename T> 10 struct if_<T, true> { 11 static const int value = 2; 12 }; 13 14 int main() { 15 printf("value: %d\n", if_<int>::value); 16 }
1 template<typename T> std::string toString(const T &x);
1 class A { 2 public: 3 std::string toString() const { 4 return std::string("toString from class A"); 5 } 6 }; 7 8 class B { 9 };
1 template<typename T> 2 struct HasToStringFunction { 3 template<typename U, std::string (U::*)() const > 4 struct matcher; 5 6 template<typename U> 7 static char helper(matcher<U, &U::toString> *); 8 9 template<typename U> 10 static int helper(...); 11 12 enum { value = sizeof(helper<T>(NULL)) == 1 }; 13 };
这里有两个helper方法, 第一个匹配精确度要高于第二个. 因此, 编译器会先尝试用U和U::toString去实例化一个matcher去匹配helper, 对于A这是能通过的, 但是对于B, 由于B::toString不存在, 这个时候编译器实际上就已经发现错误了,但是根据SFINAE原则这个只能算是模板匹配失败,不能算错误,所以编译器会跳过这次对matcher的匹配。但是跳过了以后也就没有别的匹配了,所以整个第一个helper来说对B都是不能匹配成功的,这个时候优先级比较低的第二个helper自然就能匹配上了。
1 template <bool> 2 struct ToStringWrapper {}; 3 4 template<> 5 struct ToStringWrapper<true> { 6 template<typename T> 7 static std::string toString(T &x) { 8 return x.toString(); 9 } 10 }; 11 12 template<> 13 struct ToStringWrapper<false> { 14 template<typename T> 15 static std::string toString(T &x) { 16 return std::string(typeid(x).name()); 17 } 18 }; 19 20 template<typename T> 21 std::string toString(const T &x) { 22 return ToStringWrapper<HasToStringFunction<T>::value>::toString(x); 23 } 24 25 int main() { 26 A a; 27 B b; 28 29 std::cout << toString(a) << std::endl; 30 std::cout << toString(b) << std::endl; 31 }
这里有两个小技巧, 一个是sizeof()一个函数, 返回的是函数返回值的大小. 另外一个是U::*表示类成员函数指针. 比如std::string (*)() const 表明这是一个函数指针, 而std::string (U::*)() const表示这是一个类的成员函数.
1 template <typename T> 2 class is_class { 3 template <typename U> 4 static char helper(int U::*); 5 template <typename U> 6 static int helper(...); 7 public: 8 static const bool value = sizeof(helper<T>(0)) == 1; 9 };
1 template <typename T1, typename T2> 2 struct is_same { 3 static const bool value = false; 4 }; 5 6 template <typename T> 7 struct is_same<T, T> { 8 static const bool value = true; 9 }; 10 11 template<typename Base, typename Derived, bool = (is_class<Base>::value && is_class<Derived>::value)> 12 class is_base_of { 13 template <typename T> 14 static char helper(Derived, T); 15 static int helper(Base, int); 16 struct Conv { 17 operator Derived(); 18 operator Base() const; 19 }; 20 public: 21 static const bool value = sizeof(helper(Conv(), 0)) == 1; 22 }; 23 24 template <typename Base, typename Derived> 25 class is_base_of<Base, Derived, false> { 26 public: 27 static const bool value = is_same<Base, Derived>::value; 28 }; 29 30 template <typename Base> 31 class is_base_of<Base, Base, true> { 32 public: 33 static const bool value = true; 34 };
标签:
原文地址:http://www.cnblogs.com/gx520/p/4614717.html