本系列文章从零开始介绍C++模版元编程,需要有C++基础。
函数模版 1 2 3 4 5 6 7 template  <typename  T>T add (T const  a, T const  b)   {  return  a + b; } auto  a = add (42 , 21 );auto  d = add <double >(41.0 , 21 ); 
类模版 1 2 3 4 5 6 7 8 9 10 11 12 template  <typename  T>class  wrapper  {public :	wrapper (T const  v) : value (v) {}   T const & get ()  const   { return  value; } private :  T value; }; wrapper a (1 )  ; wrapper<int > b (2 )  ;
成员函数模版 模版类的成员函数 1 2 3 4 5 6 7 8 9 template  <typename  T>class  comoosition  {public :  T add (T const  a, T const  b)   {     return  a + b;   } }; composition<int > c; c.add (12 ,32 ); 
非模版类的成员函数模版 1 2 3 4 5 6 7 8 9 10 class  compotion  {public :  template  <typename  T>   T add (T const  a, T const  b)   {     return  a + b;   } }; compostion c; c.add <int >(12 ,13 ); c.add (1 ,2 ); 
类模版的成员函数模版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 template  <typename  T>class  wrapper  {pbulic:   wrapper (T const  v) : value (v) {}   T const & get ()  const   { return  value; }      template  <typename  U>   U as ()  const   {     return  static_cast <U>(value);   } private :  T value; }; wrapper<double > a (42.1 )  ;auto  d = a.get ();auto  b = a.as <int >();
模版参数 类型模版参数 1 2 3 4 5 6 7 8 template  <typename  T> class  wrapper  {};template  <typename  T = int > class  wrapper {};template  <typename ... T> class  wrapper  {};
非类型模版 1 2 3 4 5 6 7 8 template  <int  V>class  foo  {};template  <int  V = 42 >class  foo {};template  <int ... V>class  foo  {};
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 template  <typename  T, size_t  S>class  buffer  {  T data_[S]; public :  constexpr  T const  * data ()  const  return  data_; }   constexpr  T& operator [](size_t  const  index) {     return  data_[index];   }   constexpr  T const & operator [] (size_t  const  index) const  {     return  data_[index];   } }; buffer<int , 10 > b1;  buffer<int , 2 *5 > b2; 
看一种更常见的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct  device  {  virtual  void  output ()  0 ;   virtual  ~device () {} }; template  <void  (*action) ()>struct  smart_device  : device {  void  output ()  override       (*action) ();   } }; void  say_hello_in_english ()    std::cout << "Hello, world!\n" ; } auto  w1 = std::make_unique<smart_device<&say_hello_in_english>>();w1->output (); 
双重模版参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 template  <typename  T> class  simple_wrapper  {public :	T value;  }; template  <typename  T> class  fancy_wrapper  {public :	fancy_wrapper (T const  v) :value (v) {}    	T const & get ()  const   { return  value; }    	template  <typename  U> U as ()  const   { 		return  static_cast <U>(value);    }    private :   T value; }; template  <typename  T, typename  U, template <typename > typename  W = fancy_wrapper>class  wrapping_pair {public :	wrapping_pair (T const  a, U const  b) : item1 (a), item2 (b) { } 	W<T> item1;   W<U> item2; }; 
默认模版参数 1 2 3 4 5 template  <typename  T = int > class  foo {  };template  <typename  T = int , typename  U = double > class  bar {  };
1 2 3 4 template  <typename  T = int , typename  U> class  bar { }; template  <typename  T = int , typename  U> void  func () {} 
1 2 3 4 5 template  <typename  T = int > struct  foo;template  <typename  T = int > struct  foo {};
模版实例化 模版实例化可以是显式的也可以是隐式的。
隐式实例化 1 2 3 4 5 6 7 8 9 10 11 12 template  <typename  T>struct  foo  {  void  f ()   }; int  main ()   	foo<int > *x;    foo<int > p;     foo<int > p1;    foo<double > *q;  	return  0 ; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 template  <typename  T>struct  foo  {  static  T data; }; template  <typename  T> T foo<T>::data = 0 ;int  main ()    foo<int > a;   foo<double > b;   foo<double > c;   std::cout << a.data << '\n' ;    std::cout << b.data << '\n' ;    std::cout << c.data << '\n' ;       b.data = 42 ;      std::cout << a.data << '\n' ;    std::cout << b.data << '\n' ;    std::cout << c.data << '\n' ;  } 
显示实例化 显示实例化分为显示实例化定义和显示实例化声明。
1 2 3 4 5 6 template  class -key template -name <argument-list>template  return -type name <argument-list> (parameter-list);template  return -type name (parameter-list);
1 2 3 4 5 6 7 8 9 10 11 12 13 namespace  ns {  template  <typename  T>   struct  wrapper  {     T value;   };   template  struct  wrapper <int >;  } template  struct  ns ::wrapper<double >; int  main ()     } 
1 2 3 4 5 6 7 8 9 namespace  ns {  template  <typename  T>   T add (T const  a, T const  b)   {     return  a + b;   }      template  int  add (int , int )  } template  double  ns::add (double , double ) 
模版特化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 template  <typename  T>struct  is_floatiog_point  {  constexpr  static  bool  value = false ; }; template  <>struct  is_floating_point <float > {  constexpr  static  bool  value = true ; }; template  <>struct  is_floating_point  <double >{  constexpr  static  bool  value = true ; }; template <>struct  is_floating_point  <long  double > {  constexpr  static  bool  value = true ; }; 
变量模版 别名模版 lambda 模版