C++11的类型推导详解

auto & decltype

关于C++11新特性,最先提到的肯定是类型推导,C++11引入了auto和decltype关键字,使用他们可以在编译期就推导出变量或者表达式的类型,方便开发者编码也简化了代码。

auto

auto可以让编译器在编译器就推导出变量的类型,话不多说上代码:

auto a = 10; // 10是int型,可以自动推导出a是int

int i = 10;
auto b = i; // b是int型

auto d = 2.0; // d是double型

这就是auto的基本用法,可以通过=右边的类型推导出变量的类型。

auto推导规则

直接看代码

代码1:

int i = 10;
auto a = i, &b = i, *c = &i; // a是int,b是i的引用,c是i的指针,auto就相当于int
auto d = 0, f = 1.0; // error,0和1.0类型不同,对于编译器有二义性,没法推导
auto e; // error,使用auto必须马上初始化,否则无法推导类型

代码2:

void func(auto value) {} // error,auto不能用作函数参数

class A {
    auto a = 1; // error,在类中auto不能用作非静态成员变量
    static auto b = 1; // error,这里与auto无关,正常static int b = 1也不可以
    static const auto int c = 1; // ok
};

void func2() {
    int a[10] = {0};
    auto b = a; // ok
    auto c[10] = a; // error,auto不能定义数组,可以定义指针
    vector<int> d;
    vector<auto> f = d; // error,auto无法推导出模板参数
}

总结一下auto的限制:

  • auto的使用必须马上初始化,否则无法推导出类型
  • auto在一行定义多个变量时,各个变量的推导不能产生二义性,否则编译失败
  • auto不能用作函数参数
  • 在类中auto不能用作非静态成员变量
  • auto不能定义数组,可以定义指针
  • auto无法推导出模板参数

再看这段代码:

int i = 0;
auto *a = &i; // a是int*
auto &b = i; // b是int&
auto c = b; // c是int,忽略了引用

const auto d = i; // d是const int
auto e = d; // e是int

const auto& f = e; // f是const int&
auto &g = f; // g是const int&

首先介绍下cv是指const 和volatile

  • 在不声明为引用或指针时,auto会忽略等号右边的引用类型和cv限定
  • 在声明为引用或者指针时,auto会保留等号右边的引用和cv属性
什么时候使用auto

这里没有绝对答案,只能说一下我自己的理解,个人认为在不影响代码代码可读性的前提下尽可能使用auto是蛮好的,复杂类型就使用auto,int、double这种就没有必要使用auto了吧,看下面这段代码:

auto func = [&] {
        cout << "xxx";
}; // 对于func你难道不使用auto吗,反正我是不关心lambda表达式究竟是什么类型。

auto asyncfunc = std::async(std::launch::async, func);
// 对于asyncfunc你难道不使用auto吗,我是懒得写std::futurexxx等代码,而且我也记不住它返回的究竟是什么...

decltype

上面介绍auto用于推导变量类型,而decltype则用于推导表达式类型,这里只用于编译器分析表达式的类型,表达式实际不会进行运算,上代码:

int func() { return 0; }
decltype(func()) i; // i为int类型

int x = 0;
decltype(x) y; // y是int类型
decltype(x + y) z; // z是int类型

注意:decltype不会像auto一样忽略引用和cv属性,decltype会保留表达式的引用和cv属性

cont int &i = 1;
int a = 2;
decltype(i) b = 2; // b是const int&
decltype推导规则

对于decltype(exp)有

  • exp是表达式,decltype(exp)和exp类型相同
  • exp是函数调用,decltype(exp)和函数返回值类型相同
  • 其它情况,若exp是左值,decltype(exp)是exp类型的左值引用
int a = 0, b = 0;
decltype(a + b) c = 0; // c是int,因为(a+b)返回一个右值
decltype(a += b) d = c;// d是int&,因为(a+=b)返回一个左值

d = 20;
cout << "c " << c << endl; // 输出c 20

关于左值和右值知识点后续程序喵会介绍的,请关注哦~

auto和decltype的配合使用

auto和decltype一般配合使用在推导函数返回值的类型问题上。

下面这段代码

template<typename T, typename U>
return_value add(T t, U u) { // t和v类型不确定,无法推导出return_value类型
    return t + u;
}

上面代码由于t和u类型不确定,那如何推导出返回值类型呢,我们可能会想到这种

template<typename T, typename U>
decltype(t + u) add(T t, U u) { // t和u尚未定义
    return t + u;
}

这段代码在C++11上是编译不过的,因为在decltype(t +u)推导时,t和u尚未定义,就会编译出错,所以有了下面的叫做返回类型后置的配合使用方法:

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}

返回值后置类型语法就是为了解决函数返回制类型依赖于参数但却难以确定返回值类型的问题。

关于C++11类型推导问题你看懂了吗?下去多多实践吧,记得关注程序喵哦~
更多文章,请关注我的V X 公 主 号:程序喵大人,欢迎交流。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359