// Copyright (c) 2011 The Chromium Authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file.#ifndef BASE_TEMPLATE_UTIL_H_#define BASE_TEMPLATE_UTIL_H_#include <cstddef> // For size_t.#include "build/build_config.h"namespace base {// template definitions from tr1template<class T, T v>struct integral_constant { static const T value = v; typedef T value_type; typedef integral_constant<T, v> type;};template <class T, T v> const T integral_constant<T, v>::value;最基本的true/false 类型, 内部有static,内部有static。 bool成员= true/false, 其他trait类型根据匹配结果继承相应的true_type/false_typetypedef integral_constant<bool, true> true_type;typedef integral_constant<bool, false> false_type;假如T是指针,模板匹配会特偏化匹配到第二个,继承true_typetemplate <class T> struct is_pointer : false_type {};template <class T> struct is_pointer<T*> : true_type {};// Member function pointer detection up to four params. Add more as needed// below. This is built-in to C++ 11, and we can remove this when we switch.判断一个函数是否为某一类成员函数(最多4个参数)template<typename T>struct is_member_function_pointer : false_type {};假如下面的模板匹配没有匹配,它被认为是一个非类成员函数, false_type第一次知道原来的模板可以用到这个程度,甚至可以表示类成员函数。0参数templatete <typename R, typename Z>struct is_member_function_pointer<R(Z::*)()> : true_type {};template <typename R, typename Z>struct is_member_function_pointer<R(Z::*)() const> : true_type {};1参数templatete <typename R, typename Z, typename A>struct is_member_function_pointer<R(Z::*)(A)> : true_type {};template <typename R, typename Z, typename A>struct is_member_function_pointer<R(Z::*)(A) const> : true_type {};templatete2参数 <typename R, typename Z, typename A, typename B>struct is_member_function_pointer<R(Z::*)(A, B)> : true_type {};template <typename R, typename Z, typename A, typename B>struct is_member_function_pointer<R(Z::*)(A, B) const> : true_type {};templatete3参数 <typename R, typename Z, typename A, typename B, typename C>struct is_member_function_pointer<R(Z::*)(A, B, C)> : true_type {};template <typename R, typename Z, typename A, typename B, typename C>struct is_member_function_pointer<R(Z::*)(A, B, C) const> : true_type {};templatete4参数 <typename R, typename Z, typename A, typename B, typename C, typename D>struct is_member_function_pointer<R(Z::*)(A, B, C, D)> : true_type {};template <typename R, typename Z, typename A, typename B, typename C, typename D>struct is_member_function_pointer<R(Z::*)(A, B, C, D) const> : true_type {};判断class T 与 class U是否为同一类型,template <class T, class U> struct is_same : public false_type {};template <class T> struct is_same<T,T> : true_type {};判断数组类型templatete是否为数组类型<class> struct is_array : public false_type {};template<class T, size_t n> struct is_array<T[n]> : public true_type {};template<class T> struct is_array<T[]> : public true_type {};判断是否为non const template引用template引用 <class T> struct is_non_const_reference : false_type {};template <class T> struct is_non_const_reference<T&> : true_type {};template <class T> struct is_non_const_reference<const T&> : false_type {};判断const类型templatete是否属于const类型 <class T> struct is_const : false_type {};template <class T> struct is_const<const T> : true_type {};判断是否为voidtemplatetetet <class T> struct is_void : false_type {};template <> struct is_void<void> : true_type {};namespace internal {// Types YesType and NoType are guaranteed such that sizeof(YesType) <// sizeof(NoType).正如注释所说,必须保证yestype和Notype的size不同,以后才能有效使用.typedef char YesType;struct NoType { YesType dummy[2];};// This class is an implementation detail for is_convertible, and you// don't need to know how it works to use is_convertible. For those// who care: we declare two different functions, one whose argument is// of type To and one with a variadic argument list. We give them// return types of different size, so we can use sizeof to trick the// compiler into telling us which function it would have chosen if we// had called it with an argument of type From. See Alexandrescu's// _Modern C++ Design_ for more details on this sort of trick.converthelper本质上是利用C++本身的函数参数转换,从实现中也可以看出,不同类型的Test函数是基于适应不同类型的。如果From类型可以在函数参数传输中转换为To,则为Yestype, 否则Notype, 而 Create函数的作用纯粹是传递From类型。struct ConvertHelper { template <typename To> static YesType Test(To); template <typename To> static NoType Test(...); template <typename From> static From& Create();};这个trait参考了boost库的is_class, 它的前提是只有class/union/struct,它将包含一个void(C::*)(void)类型函数, 所以下面的Test在模板匹配时会匹配到第一个Test函数,返回Yestype, 相反,返回Notype, 实际使用时要注意,调用的是Test<T>(0)// Used to determine if a type is a struct/union/class. Inspired by Boost's// is_class type_trait implementation.struct IsClassHelper { template <typename C> static YesType Test(void(C::*)(void)); template <typename C> static NoType Test(...);};} // namespace internal// Inherits from true_type if From is convertible to To, false_type otherwise.//// Note that if the type is convertible, this will be a true_type REGARDLESS// of whether or not the conversion would emit a warning.流程如下:首先,ConvertHelperper::Create<From>()获得From类型,然后ConvertHelper::Test<To>(From类型)看能不能转换。如果可以,返回yestype,使is_convertible的struct变成integral_constant<bool,true>,以后可以通过is_convertible的value获得true/false.template <typename From, typename To>struct is_convertible : integral_constant<bool, sizeof(internal::ConvertHelper::Test<To>( internal::ConvertHelper::Create<From>())) == sizeof(internal::YesType)> {};与上述原理相同,true//通过返回type和yestype是否size获得true/falsetemplate <typename T>struct is_class : integral_constant<bool, sizeof(internal::IsClassHelper::Test<T>(0)) == sizeof(internal::YesType)> {};template<bool B, class T = void>struct enable_if {};template<class T>struct enable_if<true, T> { typedef T type; };} // namespace base#endif // BASE_TEMPLATE_UTIL_H_