C++常用新特性(一)


总结学习的一些常用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, 表示未计算表达式的值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值