部分转http://www.cnblogs.com/QG-whz/p/4951177.html和http://www.cnblogs.com/QG-whz/p/4952980.html文章的内容,可以直接看这两篇,比我写的清晰很多,自己的仅供记录。
一.函数模板
eg:
1 template<typename NT> 2 NT sum(int count,NT data1 ...)//累加 3 { 4 va_list arg_ptr;//参数列表的指针 5 va_start(arg_ptr, count);//限定从count开始,限定多少个参数 6 NT sumres(0); 7 for (int i = 0; i < count;i++) 8 { 9 sumres += va_arg(arg_ptr, NT); 10 } 11 va_end(arg_ptr);//结束 12 return sumres; 13 }
参数至少要有一个是模板类型。
二.enum枚举类型
与c不同的地方是强类型,可以设置数据的类型,两种初始化方法
1 enum c:char{red,kk,tt,yy}; 2 int main() 3 { 4 c mc=c::red; 5 c mc1=c:;kk; 6 c mcx='A'; //Error: invalid conversion from 'char' to 'c' [-fpermissive] 7 }
三.auto类型与decltype类型
1 double v; 2 auto c=&v; 3 cout<<typeid(c).name();
auto用途
1.用于代替冗长复杂、变量使用范围专一的变量声明。
2.在定义模板函数时,用于声明依赖模板参数的变量类型。
3.模板函数依赖于模板参数的返回值
1 template <typename _Tx, typename _Ty> 2 auto multiply(_Tx x, _Ty y)->decltype(_Tx*_Ty) 3 { 4 return x*y; 5 }
4.函数参数或模板参数不允许使用auto
5.auto变量必须在定义时初始化。
6.如果初始化表达式是引用,则去除引用语义。
1 #include<iostream> 2 #include<typeinfo> 3 4 int main() 5 { 6 int a = 10; 7 int &b = a; 8 9 auto c = b;//c的类型为int而非int&(去除引用) 10 auto &d = b;//此时c的类型才为int& 11 c = 100; 12 std::cout <<b << std::endl; 13 std::cout << a<< std::endl; 14 std::cin.get(); 15 }
7.如果初始化表达式为const或volatile(或者两者兼有),则除去const/volatile语义。
1 const int a1 = 10; 2 auto b1= a1; //b1的类型为int而非const int(去除const) 3 const auto c1 = a1;//此时c1的类型为const int 4 b1 = 100;//合法 5 c1 = 100;//非法
8.如果auto关键字带上&号,则不去除const语意。
1 const int a2 = 10; 2 auto &b2 = a2;//因为auto带上&,故不去除const,b2类型为const int 3 b2 = 10; //非法
9.初始化表达式为数组时,auto关键字推导类型为指针,若表达式为数组且auto带上&,则推导类型为数组类型。
1 int a3[3] = { 1, 2, 3 }; 2 auto b3 = a3; 3 auto & b7 = a7; 4 cout << typeid(b7).name() << endl; //vs显示 int[3] 5 cout << typeid(b3).name() << endl; //int *
decltype函数用途
1.泛型编程中结合auto,用于追踪函数的返回值类型
2.重用匿名类型
1 struct 2 { 3 int d ; 4 doubel b; 5 }anon_s; 6 decltype(anon_s) as ;//定义了一个上面匿名的结构体
3.与using/typedef合用,用于定义类型。
1 using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型 2 using ptrdiff_t = decltype((int*)0 - (int*)0); 3 using nullptr_t = decltype(nullptr); 4 vector<int >vec; 5 typedef decltype(vec.begin()) vectype; 6 for (vectype i = vec.begin; i != vec.end(); i++) 7 { 8 //... 9 }
4.推导4大规则
1.如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么的decltype(e)就是e所命名的实体的类型。此外,如果e是一个被重载的函数,则会导致编译错误。
2. 否则 ,假设e的类型是T,如果e是一个将亡值,那么decltype(e)为T&&
3.否则,假设e的类型是T,如果e是一个左值,那么decltype(e)为T&。
4.否则,假设e的类型是T,则decltype(e)为T。
1 int i = 4; 2 int arr[5] = { 0 }; 3 int *ptr = arr; 4 struct S{ double d; }s ; 5 void Overloaded(int); 6 void Overloaded(char);//重载的函数 7 int && RvalRef(); 8 const bool Func(int); 9 10 //规则一:推导为其类型 11 decltype (arr) var1; //int 标记符表达式 12 13 decltype (ptr) var2;//int * 标记符表达式 14 15 decltype(s.d) var3;//doubel 成员访问表达式 16 17 //decltype(Overloaded) var4;//重载函数。编译错误。 18 19 //规则二:将亡值。推导为类型的右值引用。 20 21 decltype (RvalRef()) var5 = 1; 22 23 //规则三:左值,推导为类型的引用。 24 25 decltype ((i))var6 = i; //int& 26 27 decltype (true ? i : i) var7 = i; //int& 条件表达式返回左值。 28 29 decltype (++i) var8 = i; //int& ++i返回i的左值。 30 31 decltype(arr[5]) var9 = i;//int&. []操作返回左值 32 33 decltype(*ptr)var10 = i;//int& *操作返回左值 34 35 decltype("hello")var11 = "hello"; //const char(&)[9] 字符串字面常量为左值,且为const左值。 36 37 38 //规则四:以上都不是,则推导为本类型 39 40 decltype(1) var12;//const int 41 42 decltype(Func(1)) var13=true;//const bool 43 44 decltype(i++) var14 = i;//int i++返回右值
左值,右值可以由is_lvalue_reference和is_rvalue_reference来确定。
1 #include<iostream> 2 #include <type_traits> 3 4 int main() 5 { 6 int i = 0; 7 std::cout << std::is_lvalue_reference<decltype(++i)>::value <<std:: endl; 8 std::cout << std::is_rvalue_reference<decltype(i++)>::value << std::endl; 9 std::cin.get(); 10 }
四.内联函数
函数上代替define,尽量简略,避免循环,由编译器判断内联函数是否能够内联
五.new/delete重载