好久没更新了博客了,这段时间笔记都记在便利贴粘书上,结果便利贴竟然不粘了,哭唧唧QAQ
另外。。感觉CSDN创作博客的界面突然好用了很多??
-----------------------------------------------------------------------------------------------------------------------
auto关键字
-----------------------------------------------------------------------------------------------------------------------
auto在编译时通过初始化表达式进行类型推导,所以超级适用于泛型编程,省略了敲一大堆的模板参数。
vector<vector<int>> v; auto it = v.begin();//嗯。。偷个懒
(虽然在C11之前就存在auto,不过那时auto声明的变量为自动变量)
对于auto有以下几点注意事项:
1.使用时要初始化
auto a1 = 10,a2 = 11;//true auto a3 = 10,a4 = 0.01;//error,定义的一组auto序列必须能推导成同一类型
2、如果初始化表达式是引用,类型则要去掉引用
int c1 = 1; int &c2 = c1; auto d = c2; cout<<typeid(d).name();//int
3、若初始化表达式为const/volatile,则去掉const/volatie,若auto &则不需要去除。
const int d1 = 1; //auto f = d1;//int const auto f = d1;//const int f = 10;//error auto &f2 = d1;//const int f2 = 10;//error
4、若初始化表达式为数组,则得到指针类型,若auto &,则得到数组类型
int arr[2] = {1,1}; auto e = arr; cout<<typeid(e).name();//int * auto &e2 = arr; cout<<typeid(e2).name();//int [2]5、auto不能用作参数
void fun(int a,auto b)//error {} vector<auto> v;//error
6、auto不能看作一个真正的类型,不允许对auto使用sizeof或者typeid
-----------------------------------------------------------------------------------------------------------------------
decltype操作符
-----------------------------------------------------------------------------------------------------------------------
用于查询表达式的数据类型,不需要对操作数求值。也是适用于泛型算法。
int a; const int fun(); const int &&fun2(); struct A{char b;}; const A *aa = new A(); decltype(a) x1;//int decltype(fun()) x2;//const int,需要初始化 decltype(fun2()) x3;//const int &&需要初始化 decltype(aa->b) x4;//char decltype((aa->b)) x5;//const char&需要初始化,(aa->b)非标识符表达式非访问表达式,
未指向明明对象,是一个左值
对于T e; decltype(e)有如下规则:
1、若e指向局部变量、命名空间作用域变量、静态成员变量、函数参数、则得到的是e的声明类型
2、若e是左值(存储在计算机内存的可寻址的)则得到的是T&;
3、若ee是一个X值,得到的是T&&;
4、若e是一个纯右值,得到的是T;
(这里补充一下,C11中,右值分为纯右值prvalue和将亡值xvalue,纯右值没有名字不能取地址(比如临时量),
将亡值通常是将要被移动的对象(比如返回右值引用T&&的函数返回值、std::move的返回值,或者转换为T&&的类型转换函数的返回值)
https://blog.csdn.net/hyman_yx/article/details/52044632)。
其实比较不理解T&&是什么鬼,于是又百度了一下:T&&理解为右值引用,将变量绑定到一个临时量上,一般是函数返回值
于是呢,上面的代码可以写成:
decltype(fun2()) x3 = fun();
//const int &&,这样可以减少函数返回操作并且赋值操作是new,delete,copy等,当然也可作为参数哈
-----------------------------------------------------------------------------------------------------------------------
nullptr
-----------------------------------------------------------------------------------------------------------------------
nullptr是解决了NULL二义性的新类型
void F(int *p) { cout<< "pointer" <<endl; } void F(int p) { cout<<"int"<<endl; } int main() { int *p = nullptr; int *q = NULL; // cout<<(p==q);// 1,说明他们都代表空指针 //int a = nullptr; // error,nullptr不能转型为int F(NULL); //int F(0); // int,(在C++98中编译失败,有二义性) //其实看得出来在C11下,编译器将NULL解释为0 F(nullptr);//pointer }
-----------------------------------------------------------------------------------------------------------------------
Lambda
---------------------------------------------------------------------------------------------------------------------
Lamdba可以创建并定义匿名的函数对象。
[capture](parameters)->return-type{body}
[ ]捕获说明符,是lambda表达式的开始,parameters是匿名的lambda函数参数列表,
->return-type是返回值类型,嘛没有就省略。{body}是函数体。
auto fun = [](){cout<<"hahahh";}; fun();//hahahh
嗯。。。具体的请看这里https://blog.csdn.net/augusdi/article/details/11773943
lamdba加上之前的auto和decltype有奇效
比如说:
//C++11 template<typename T, typename U> auto myFunc(T&& t, U&& u) -> decltype (forward<T>(t) + forward<U>(u)) { return forward<T>(t) + forward<U>(u); }; //C++14 template<typename T, typename U> decltype(auto) myFunc(T&& t, U&& u) { return forward<T>(t) + forward<U>(u); };代码出处:https://blog.csdn.net/yhl_leo/article/details/50865552 此处定义一个求和模板函数
-----------------------------------------------------------------------------------------------------------------------
可变长参数模板
---------------------------------------------------------------------------------------------------------------------
看看这个新的数据类型:tuple(N元组,可以传入多个不同类型的数据)
#include <tuple> using namespace std; tuple<int,int>f() { int x = 5; return make_tuple(x,7); } int main() { auto a = make_tuple(1,1.1, "C++ 11"); auto a2 = make_tuple(1, 2.0, "C++ 11", 'c'); cout<<get<0>(a)<<","<<get<1>(a)<<","<<get<2>(a2)<<endl;//获得元组值 int c,d; tie(c,d) = f(); cout<<c<<","<<d;//用tie解包tuple,f()的返回值(tuple<int&,int&>)赋给c,d变量 }
此处输出:1,1.1,C++ 11
5,7
关于tuple可以看看这个http://www.cnblogs.com/qicosmos/p/3318070.html
看了别人的博客,貌似可以有这种操作???为什么我的不行
- auto t2 = make_tuple(1, 2.0, "C++ 11", {1, 0, 2});
-----------------------------------------------------------------------------------------------------------------------
更便捷的初始化方式
---------------------------------------------------------------------------------------------------------------------
据说在C11下,我们可以这样做,
- int arr[3]{1, 2, 3};
- vector<int> iv{1, 2, 3};
- map<int, string>{{1, "a"}, {2, "b"}};
- string str{"Hello World"};
以上代码来自http://developer.51cto.com/art/201312/422379.htm
为什么是据说呢,因为VS2012并不完全支持C11呀,包括这个就不支持