总结学习的一些常用C++新特性:auto , lambda, decltype, nullptr.
参考:
https://zh.cppreference.com/w/cpp/language/lambda
https://en.wikipedia.org/wiki/C%2B%2B14
1. 自动类型推导auto
C++11中引入了auto, 用于通过初始化表达式自动推导出变量的数据类型,使用例程如下:
auto a = 5;
auto a = 5;
auto b = 5.0;
auto srt = "hello!";
std::vector<double> vec;
//std::vector<double>::iterator it = vec.begin();
auto it = vec.begin();
auto f = new foo();
auto fptr = std::shared_ptr<foo>(new foo);
在函数传递参数中使用auto(C++14特性):
#include<iostream>
void fun(auto& a, auto& b){
auto c = a;
auto d = b;
std::cout<<c<<" "<<d<<std::endl;
}
auto fun2(){
auto a = 1.8;
return a;
}
int main(int argc, char**argv){
auto a = 1;
auto b = 2.5;
fun(a,b);
auto fa = fun2();
std::cout<<fa<<std::endl;
return 0;
}
auto在模板中的作用例程,模板中使用auto可以精简模板参数:
模板中不使用auto时:
template<typename T1, typename T2>
void T1CreateT2(const T1& t1){
T2* t2 = t1.create();
}
模板中使用auto:
template<typename T1>
void T1CreateT2(const T1& t1){
auto t2 = t1.create();
}
在for循环中使用auto:
int main(int argc, char** argv){
std::vector<int> vec = {1,2,3,4,5};
for(auto v : vec)
std::cout<<v<<" ";
std::cout<<std::endl;
return 0 ;
}
综上可见,C++新特性引入auto 可使代码更加整洁,且可以提高程序员的编程效率.
2. lambda表达式
C/C++中没有函数嵌套的定义,因此引入lambda表达式,对于一些小函数,可通过lambda表达式实现,增加代码紧凑性,便于阅读和理解.
#include <iostream>
int main(int argc, char *argv[])
{
auto a = 5;
auto b = 5.0;
auto fun1 = [a](auto v1, auto v2)->int{return v1+v2+a;};
auto result1 = fun1(2,3);
std::cout<<"fun1: "<<result1<<std::endl<<std::endl;
auto fun2 = [=](auto v1, auto v2)->int{return v1+v2+a+b;};
auto result2 = fun2(2,3);
std::cout<<"fun2: "<<result2<<std::endl<<std::endl;
auto fun3 = [=,&a](auto v1, auto v2)->int{
a += 2;
return v1+v2+a+b;
};
auto result3 = fun3(2,3);
std::cout<<"fun3: "<<result3<<std::endl;
std::cout<<"a: "<<a<<std::endl<<std::endl;
auto fun4 = [b,&a](auto v1, auto v2)mutable->int{
a = a+1;
b = b+1.0;
std::cout<<"b in fun4: "<<b<<std::endl;
return v1+v2+a+b;
};
auto result4 = fun4(2,3);
std::cout<<"fun4: "<<result4<<std::endl;
std::cout<<"b out fun4: "<<b<<std::endl;
auto fun5 = [](int x,int y)->int{return x+2*y;}(5,3);
std::cout<<"fun5: "<<fun5<<std::endl;
return 0;
}
/*
输出结果:
fun1: 10
fun2: 15
fun3: 17
a: 7
b in fun4: 6
fun4: 19
b out fun4: 5
fun5: 11
[a]: 表示外部变量a以传值方式传递,可读不可写,此时表达式函数体内不可访问外部变量b.
[=]: 表示所有外部变量以传值方式传递,可读不可写,此时表达式函数体内可以访问所以外部变量a和b.
[=,&a]:表示变量a以引用方式传递,可读可写;其他所以外部变量以传值方式传递,可读不可写
->int:表示fun表达式返回值类型为int
{语句;}函数体
(auto v1, auto v2): 表达式函数形参
mutable:表示以非引用传递的参数也可读可写,但不可以返回
函数体外的'()': 表示传入参数,在fun5表达式中表示传入x = 5, y = 3
*/
在for_each中使用:
std::vector<int> vec{1,2,3,4,5};
int b = 2;
std::cout<<"vec: ";
for_each(vec.begin(),vec.end(),
[b](int& x){
x += b;
std::cout<<x<<" ";
});
std::cout<<std::endl;
///输出: vec: 3 4 5 6 7
3. nullptr指针
原来C++中表示空指针用NULL, 具有二义性,c++11为解决空指针的二义性引入nullptr指针.
#include <iostream>
#include<assert.h>
void Fun(int a){
std::cout<<"1_input: "<<a<<std::endl;
}
void Fun(int* p){
assert(p != NULL);
std::cout<<"2_input : "<<*p<<std::endl;
}
int main(int argc, char *argv[])
{
int a = NULL;
//int a = nullptr;//编译失败,nullptr指针不能转化为int类型.
int* b = NULL;
Fun(nullptr);
//Fun(NULL);//编译失败, 存在二义性
return 0;
}
4. decltype自动类型推导
decltype和auto都可以进行自动类型推导,但他们有几个差异点:
(1). auto需要初始化操作, decltype 除推导引用外不需要初始化.
(2). auto 推导表达式类型时计算了表达式的值, decltype只是推导出表达式返回类型,并不只算标定式的值.
(3). auto 忽略变量的const性质, decltype则保留变量的const性质.
(4). 对于引用, auto 推导出引用的原有类型, 而decltype则推导出引用
用法如下:
int val = 5;
decltype(val) val1 = 6;//val1为int类型, 初始化赋值为6
decltype(val) val2; //val2为int类型, 可以不用初始化
//auto val3;//编译不通过, 因为auto必须初始化
const int vala = 7;
decltype(vala) vala1 = 6;//vala1为const int类型, 初始化赋值为6
// vala1 = 8; //编译不通过
auto vala2 = vala;
vala2 = 8; //编译通过,因为vala2类型为int类型而不是const int
int valb = 8;
int& valb1 = valb;
decltype(valb1) valb2 = valb; //valb2为valb的引用
valb2 = 10;
std::cout<<"valb: "<<valb<<std::endl;//此时valb == 10
auto valb3 = valb;
valb3 = 11;
std::cout<<"valb: "<<valb<<std::endl;//此时valb仍为10,
//因为valb3不是valb的引用, valb3值的改变并不影响valb的值
auto fun = [](auto a, auto b)->int{
int sum = a + b;
std::cout<<"sum: "<<sum<<std::endl;
return sum;
};
auto fun1 = fun(1,2);
std::cout<<"fun1: "<<fun1<<std::endl;//此时fun1类型为int, 值为3
//并打印出sum: 3,表示计算了表达式的值并返回给fun1
decltype(fun(1,2)) fun2;
std::cout<<"fun2: "<<fun2<<std::endl;//此时fun1类型为int, 值为0
//并不打印出sum: 3, 表示未计算表达式的值