标签:字符 log 重载函数 枚举 值类型 handle std 类型形参 不同
泛型编程是指独立与任何类型的方式编写代码。泛型编程和面向对象编程,都依赖与某种形式的多态。面向对象编程的多态性在运行时应用于存在继承关系的类,一段代码可以可以忽略基类和派生类之间的差异。在泛型编程中,编写的代码可以用作多种类型的对象。面向对象编程所依赖的多态性称为运行时多态性,泛型编程所依赖的多态性称为编译时多态性或参数式多态性。
template<typename T> inline int getMaxVal(const T& t1, const T& t2) { return t1 < t2 ? t2 : t1; }
const size_t MAXSIZE = 100; template<class T> class Stack{ private: T elements[MAXSIZE]; public: //others };
template<typename T,int X = 5> inline bool greaterThanX(const T& a) { return a >= X; } std::cout << greaterThanX(10) << std::endl;
template<class T,int MAXSIZE=100> class Stack { private: T elements[MAXSIZE]; public: //others };
3.1 隐式实例化。在使用模板函数和模板类时,不存在指定类型的模板函数和模板类的实体时,由编译器根据指定类型参数隐式生成模板函数或者模板类的实体称之为模板的隐式实例化。函数模板隐式实例化指的是在发生函数调用的时候,如果没有发现相匹配的函数存在,编译器就会寻找同名函数模板,如果可以成功进行参数类型推演,就对函数模板进行实例化。类模板隐式实例化指的是在使用模板类时才将模板实例化。
2.2 显示实例化。显示实例化也称为外部实例化。在不发生函数调用的时候将函数模板实例化,或者在不适用类模板的时候将类模板实例化称之为模板显示实例化
可变参数模板是C++11新增的特性之一,它对参数高度泛化,他能表示0到任意个数、任意类型的参数。可变模板参数之前会带有省略号,把带省略号的参数称为“参数包”,它里面包含了0到N(N>=0)个模版参数。我们无法直接获取参数包args中的每个参数的,只能通过展开参数包的方式来获取参数包中的每个参数,这是使用可变模版参数的一个主要特点。可变模版参数和普通的模版参数语义是一致的,所以可以应用于函数和类,即可变模版参数函数和可变模版参数类,然而,模版函数不支持偏特化,所以可变模版参数函数和可变模版参数类展开可变模版参数的方法还不尽相同。
l 递归函数方式展开参数包。通过递归函数展开参数包,需要提供一个参数包展开的函数和一个递归终止函数,递归终止函数正是用来终止递归的。
l 逗号方式展开参数包
可变参数模板类的参数包展开的方式和可变参数模板函数的展开方式不同,可变参数模板类的参数包展开需要通过模板特化和继承方式去展开,展开方式比可变参数模板函数要复杂。具体参考http://www.cnblogs.com/qicosmos/p/4325949.html
可变参数模板类是一个带可变模板参数的模板类,比如C++11中的元祖std::tuple就是一个可变模板类,它的定义如下:
template< class... Types >
class tuple;
这个可变参数模板类可以携带任意类型任意个数的模板参数:
std::tuple<int> tp1 = std::make_tuple(1);
std::tuple<int, double> tp2 = std::make_tuple(1, 2.5);
std::tuple<int, double, string> tp3 = std::make_tuple(1, 2.5, “”);
可变参数模板的模板参数个数可以为0个,所以下面的定义也是也是合法的:
std::tuple<> tp;
参考:
3. 模板参数
有些时候统一的一个模板不能解决所有的参数问题,例如统一的一个模板有时候不能编译,不能正确实例化,输出结果有问题
模板特例化:函数模板特化,类模板特化
例如:定义了一个compare的模板函数用比较定义了“<”的对象,如int,double以及自定义类型。
a. 为了处理字符串常量,compare("hi","com"),重载了
template<unsigned N,unsigned M>
int compare(const char(&p1)[N],const char(&p2)[M])
注:当比较的字符串长度相同时,GCC 4.83会认为与 int compare(const T& v1,const T& v2) 模糊,无法正确的实例化,编译不通过
test.cpp: In function ‘int main()’:
test.cpp:45:34: error: call of overloaded ‘compare(const char [6], const char [6])’ is ambiguous
cout<<compare("hello","hello")<<endl;
^
test.cpp:45:34: note: candidates are:
test.cpp:14:5: note: int compare(const T&, const T&) [with T = char [6]]
int compare(const T& v1,const T& v2)
^
test.cpp:25:5: note: int compare(const char (&)[N], const char (&)[M]) [with unsigned int N = 6u; unsigned int M = 6u]
int compare(const char(&p1)[N],const char(&p2)[M])
b.为了处理字符串指针 cout<<compare(str1,str2)<<endl;我们特化了 int compare(const T& v1,const T& v2),注意特化的格式以及参数类型。
#include<iostream> #include<cstring> using namespace std; template<typename T> int compare(const T& v1,const T& v2) { if(v1<v2) return -1; if(v2<v1) return 1; return 0; } //Notype template parameter //handle string literals,that type is const char[] template<unsigned N,unsigned M> int compare(const char(&p1)[N],const char(&p2)[M]) { return strcmp(p1,p2); } //special version of compare to handle pointers //to character arrays template<> int compare(const char* const& p1,const char* const& p2) { return strcmp(p1,p2); } int main() { const char* str1="hello"; const char* str2="hello"; cout<<compare(1,2)<<endl; //note:same string length lead to instantiate ambiguously cout<<compare("hello","hell")<<endl; //const char[] cout<<compare(str1,str2)<<endl; return 0; }
template <class T> class compare { public: bool IsEqual(T t1, T t2) { return t1 == t2; } }; int main() { char str1[] = "Hello"; char str2[] = "Hello"; compare<int> c1; compare<char *> c2; cout << c1.IsEqual(1, 1) << endl; //比较两个int类型的参数 cout << c2.IsEqual(str1, str2) << endl; //比较两个char *类型的参数 return 0; }
template<>class compare<char *> //特化(char*) 2 { 3 public: 4 bool IsEqual(char* t1, char* t2) 5 { 6 return strcmp(t1, t2) == 0; //使用strcmp比较字符串 7 } 8 };
标签:字符 log 重载函数 枚举 值类型 handle std 类型形参 不同
原文地址:http://www.cnblogs.com/wxquare/p/4743180.html