C++11系列文章之一 | 类型推导神功修炼

大家好,我是小杰。

如果读完这篇感觉到有用的知识增加了,不妨点个赞、在看和关注,鼓励一下!

很抱歉最近两周我没怎么发原创,并不是我忘记了,而是遇到了考试周,五门考试真的是太忙了(毕竟没有听课),所以我断更了,接下来我会接着更下去。

这段时间我虽然没有更文,但是我也在思考着文章的方向,我打算出几个系列,每个系列出完之后会出一篇汇总文章方便读者收藏和学习,当然我也会放到公众号下面的按钮中方便找到,目前想到的有网络框架的源码解析系列、XX天从零开发网络框架系列、C++11、14、17等系列及其应用、STL源码解析系列、Linux源码刨析系列、Go语言的入门到源码系列、包括计算机操作系统,计算机网络、数据结构等系列,这是我目前想到的,后续会有其他系列我会接着更,尽请期待!我会一直做下去!

auto类型推导

C++旧标准:

具有自动存储的局部变量

auto int i = 0   //C++98   

实际上我们一般不这样写,因为非static变量默认就是具有自动存储的局部变量

C++11:

让编译器自动推断出这个变量的类型,而不需要显式指定类型

auto基本用法

演示:

auto x = 5							//x  --> int
auto pi = new auto(1)				//pi --> int*
const auto *v = &x, u = 6			//v  --> const int* 、 u   --> const int
static auto y = 0.0					//y  --> double

int x = 0    
auto *  a = &x      //a --> int* , auto为int
auto    b = &x      //b --> int* , auto 为 int*
auto	c = x		//c --> int& ,  auto为int
auto 	d = c   	//d --> int ,  auto为int

const auto e = x	//e	--> const int
auto 	   f = e	//f --> int

const auto& g = x	//g --> const int&
auto& 		h = g	//h --> const int&    

上面就是通常会出现的所有情况,其实可以类比模板参数自动推导

auto 不能用于函数参数

auto 推导规则

黄金法则

  1. 当不声明为指针或引用时,auto的推到结果和初始化表达式抛弃引用和cv限定符(cosnt 和 volatile,下同)后类型一致
  2. 当声明为指针或引用时,auto的推到结果将保持初始化表达式的cv属性
auto 的限制
  1. 不能用于函数参数
  2. 不支持非静态成员变量的初始化
  3. main函数中auto不会被推导为数组类型,而是指针类型
auto 适用场景

场景一:

for循环中用来遍历容器

for(auto it = resultMap.begin(); it != resultMap.end(); ++i){
    //do something
}

场景二:

用于不知道如何定义变量,多与泛型有关

class Foo{
   public:
    static int get(void)
    {
        return 0;
    }
};
class Bar{
    public:
    static const char* get(void)
    {
        return "0";
    }
};

template<class A>
void func(void)    
{
    auto val = A::get();
    // ...
}

decltype 类型推导

decltype( exp )

exp 表示一个表达式

从格式上来看,decltype像sizeof ,但其用来在编译时推导出一个表达式的类型

decltype 基本用法
int x = 0
decltype(x) y = 1			//y -> int
decltype(x + y) z = 0		//z -> int

const int& i = x			
decltype(i) j = y			//j -> const int &

cosnt decltype(z) *p = &z	//*p -> const int, p -> const int *
decltype(z) * pi = &z		//*pi -> int  , pi -> int*
decltype(pi) * pp = &pi		//*pp -> int * ,pp -> int **

decltype和&结合的推导结果,与引用折叠规则有关,将在本系列后续中详细讲解

decltype 推导规则

黄金法则:

  1. exp是标识符、类访问表达式,decltype(exp) 和exp的类型一致
  2. exp是寒素调用,decltype(exp) 和返回值 的类型一致
  3. 其他情况,若exp是个左值,则 ecltype(exp) 是exp类型的左值引用,否则和exp类型一致
decltype 适用场景

decltype适用于泛型相关

场景一:

标准库中有些类型的定义

typedef decltype(nullptr) nullptr_t
typedef decltype(sizeof(0)) size_t

场景二:

通过变量表达式抽取变量类型实现简写

vector<int> v;
decltype(v):value_type i = 0

场景三:

template<class ContainerT>
class Foo
{
    decltype(ContainerT().begin()) it_;
public:
    void func(ContarinerT& container)
    {
        it_ = container.begin();
    }
    // ...
}    

auto 和 decltype结合——返回类型后置

即通过两个结合起来,使得语法更加灵活便捷

int & foo(int& i);
float foo(float& f)
template<typename T>    
auto fun(T& val)     -> decltype(foo(val))  
{
    return foo(val);
}    

小结

auto和decltype的出现不仅弥补了C++旧版标准的不足,也大大解放了开发人员的生产力,提升了效率。但是我们在使用的时候仍然需要注意,不能滥用,否则会出现我们期望得到的类型和最终程序的类型不一致,导致一些意想不到的BUG,给我维护增加了成本,适用和巧用才是正解

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星光 不服赶路人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值