C++模板是泛型编程的基础。我们平时使用的Vector,find都是实现泛型编程的。它的类型的确定发生在编译时,只有被调用了,才会实例化。
函数模板:
template<typename T>
int compare (const T &v1,const T &v2){
if(v1 < v2) return -1;
else return 1;
return 0;
}
实例化:
cout<< compare(1,0)<<endl; (自动推导类型)
类型参数可以用来作为返回类型或者函数的参数类型:
template<typename T> T foo(T *p){
T temp= *p;
return temp;
}
非类型模板参数:
template<unsigned N,unsigned M>
int compare(const char (&p)[N],const char (&p2)[M]){ //如果是非字符串类型,传入数组一般都不知道它的长度,那么我们可以利用这种方法的到传入的参数 N,M;
return strcmp(p1,p2);
}
constexpr /inline的位置放在模板参数列表之后,返回值类型之前。
如:
template <typename T> constexpr T min(const T &,const T &);
constexpr:为“常表达式函数” 默认是内联(inline)的,它的出现是为了补充C++ const 的不足的;(为了提供比较复杂点的常数计算,并且类型检查(比C define好很多),能在编译时确定)
常函数必须满足如下标准(647 号议题,2008.6):
- 非虚函数。
- 返回值和参数表都须为“字面类型(Literal Type)”。
- 函数体只能是 return expression; 的形式,expression 应为潜在的常数表达式。
- 函数体被声明为 constexpr。
- 由 expression 到返回类型的隐式转化(implicit conversion)须为常表达式允许的转化形式之一
#include <iostream>
#include <stdexcept>
// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
return n <= 1 ? 1 : (n * factorial(n-1));
}
template<int n> struct constN {
constN() { std::cout << n << '\n'; }
};
template< typename Type >
constexpr Type max( Type a, Type b ) { return a < b ? b : a; }
int main()
{
constN<6> out2;
std::cout << "4! = " ;
constN<factorial(4)> out1; // computed at compile time
volatile int k = 8; // disallow optimization using volatile
std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time
double f=5.3,d=9.0;
const double maxf=max(f,d);
std::cout<<"5.3,9.0which one is max:"<<maxf<<std::endl;
}
×××××××××××××××××××××××××××××××××××××××××××××
为任何数组类型定义一个泛式的比较函数:下面有对其double,int ,char类型进行测试的代码:
#include <vector>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
/*
other knowlege: if has .h and .cpp:
1.put the template about it's state and it'sdefine all in .h file;
2.add" template class function_name<int>" in .cpp file;
*/
/* template for function:auto to know the paramete style and variable*/
template <typename T,unsigned N,unsigned M>
const T* compare(const T (&a)[N],const T (&b)[M],unsigned &len){
unsigned i=0;
while( i < N && i < M ){
if( a[i]>b[i] ){
len=N;
return a;
}
else if(a[i]<b[i]){
len=M;
return b;
}
else i++;
}
if(i>=N){
len=M;
return b;
}
else{
len=N;
return a;
}
}
int main(){
double d_a[5]={12.3,34.5,3,2,43};
double d_b[3]={12.3,34.5,3};
int i_a[4]={2,3,4,1};
int i_b[4]={2,3,5,0};
char s_a[]="abc";
char s_b[]="abacse";
unsigned len=0,i;
const double *d_temp=compare(d_a,d_b,len);
for(i=0;i<len;i++)
cout<<d_temp[i]<<" ";
cout<<endl;
const int *i_temp=compare(i_a,i_b,len);
for(i=0;i<len;i++)
cout<<i_temp[i]<<" ";
cout<<endl;
const char *s_temp=compare(s_a,s_b,len);
for(i=0;i<len;i++)
cout<<s_temp[i]<<" ";
cout<<endl;
return 0;