2017.2.17<转>

部分转http://www.cnblogs.com/QG-whz/p/4951177.htmlhttp://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重载

posted @ 2017-02-17 22:44  acliang  阅读(209)  评论(0编辑  收藏  举报