[C++11阅读][3-3-3]decltype类型推导(中)

引子

decltype类型推导还挺复杂,有时候会出一些奇怪的错误,比如下面的程序编译不过,因为括号里的i推导成引用了。

int main() {
    int i;
    decltype(i) a;
    decltype((i)) b;
}
// cpp.cpp:5:19: error: ‘b’ declared as reference but not initialized

四规则

当程序员用decltype(e)获得类型,

  1. 如果e是一个没有带括号的标记符表达式(id-expression)或者类表达式,那么decltype(e)就是e所命名的实体的类型。此外,如果e是一个被重载的函数,则会导致编译时错误。
  2. 否则,假设e的类型是T,如果e是一个将亡值(xvalue),那么decltype(e)为T&&。
  3. 否则,假设e的类型是T,如果e是一个左值,则decltype(e)为T&。
  4. 否则,假设e的类型是T,则decltype(e)为T。
    标记符表达式就是常规理解的表达式,比如int arr[4];,arr是标记符表达式,但arr[3]就不是,已经对arr进行了操作。
    引子里的例子,a属于规则1,b属于规则3,(i)带了括号,又实实在在有地址、属于左值,因此落到了规则3。

四规则示例

int main() {
    int i = 4;
    int arr[5] = {0};
    int *ptr = arr;
    struct S { double d; } s;
    void Overloaded(int);
    void Overloaded(char);
    int && RvalRef();
    const bool Func(int);
    // 规则1
    decltype(arr) var1;  // int[5]
    decltype(ptr) var2;  // int*
    decltype(s.d) var4;  // double
    decltype(Overloaded) var5;  // error: decltype cannot resolve address of overloaded function
    // 规则2
    decltype(RvalRef()) var6 = 1;  // xrvalue, int&&
    // 规则3
    decltype(true? i : i) var7 = i;  // lvalue int&
    decltype((i)) var8 = i;  // int&
    decltype(++i) var9 = i;  // int&
    decltype(arr[3]) var10 = i;  // int&
    decltype(*ptr) var11 = i;  // int&
    decltype("lval") var12 = "lval";  // const char(&)[9]
    // 规则4
    decltype(1) var13;  // int
    decltype(i++) var14;  // int
    decltype((Func(1))) var15;  // const bool
}

上面的程序覆盖了四种规则。
关于var5,把void Overloaded(char);那行删掉就能编译通过了,没有重载的函数是可以放在decltype里的。
另外值得注意的是i++和++i那句,i++得到的是int,++i得到的是int&。这是因为++i返回的是操作后的结果,类似(i),不再是标记符表达式,有地址跟i一样,落在了规则3;i++不是i,不是规则1,但也没有地址,落在了规则4。
打印结果。

#include <type_traits>
#include <iostream>
using namespace std;
int i = 4;
int arr[5] = {};
int *ptr = arr;
int && RvalRef();
int main(){
    cout << is_rvalue_reference<decltype(RvalRef())>::value << endl; // 1
    cout << is_lvalue_reference<decltype(true? i : i)>::value << endl; // 1
    cout << is_lvalue_reference<decltype((i))>::value << endl; // 1
    cout << is_lvalue_reference<decltype(++i)>::value << endl; // 1
    cout << is_lvalue_reference<decltype(arr[3])>::value << endl; // 1
    cout << is_lvalue_reference<decltype(*ptr)>::value << endl; // 1
    cout << is_lvalue_reference<decltype("lval")>::value << endl; // 1
    cout << is_lvalue_reference<decltype(i++)>::value << endl; // 0,不是左值引用也不是右值引用,就是左值
    cout << is_rvalue_reference<decltype(i++)>::value << endl; // 0,改成is_integral就能出来1了
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353