C/C++tips3(c++11及以后)

吐槽一下,经典的c++98经过c++11和c++14的升级后,似乎一下变成了另一种编程语言了。c++11和c++14引入了大量的新特性,使我感觉c++的复杂程度一下上升了数倍。
这里的很多主题都非常复杂,我仅仅把我自己的理解大致记录下来,具体内容还是要去看看c++主题演讲

cv-qualified

在一些资料中经常看到cv-qualified type之类的词语,这里的cv就是const & volatile,即不变和易变修饰符,cv-qualified type就是以const或者volatile修饰的类型。
在使用模版函数或者auto时,根据参数的类型,编译器的类型推导会自动地推导出cv-qualified type。
例如:

// 1\. 模版函数

template<typename T>
void func(T& t) {…}
const int a = 1;
func(a);    // 模版函数参数的类型成为const int&

// 2\. auto
const int a = 3;
auto& var = a;    // var的类型成为const int&

但是,如果模版函数或者auto不是引用或者指针,那么得到的类型是去除了cv-qualified的类型。因为此时新的标识符有了独立的内存空间,对于原标识符内存空间的修饰当然不应该继续生效了。

左值和右值

C++规定:凡是能够通过取地址运算符取得变量在内存中地址的,就是左值,否则就是右值。可以这样理解:左值是存在于内存中的变量(不论是堆内存还是栈内存),而右值是仅存在于寄存器中的临时变量。

decltype

decltype可以推断一个标识符的类型,这个类型是编译时推导出的。
由于lambda表达式的类型是无名的,因此如果想要获得lambda表达式的类型,只能使用decltype(lambdaExpr)。例如:

auto f = [](int a, int b) -> int
{
    return a * b;
};

decltype(f) g = f; // lambda 的类型是独有且无名的
i = f(2, 2);
j = g(3, 3);

using和typedef

在C++11中,鼓励使用using来替代原来的typedef定义类型别名。using强制将类型名称放到等号左边,而将类型放到等号右边,提高了可读性;此外,using还支持泛型,而typedef不支持泛型。
举一个例子:

typedef int (*myFunc)(int, char*);
using myFunc = int (*)(int, char*);

类型推断(type deduction)

scott mayer的演讲阐明了一些非常容易被忽视或者混淆的基本概念,理解这些基础是理解C++11和C++14新增内容的必要知识。
https://www.youtube.com/watch?v=wQxj20X-tIU

右值引用 & 移动语义

右值引用和移动语义也是在C++11新增的词,用于解决对象在右值赋值时会不必要地进行额外操作的问题。此外,同样利用C++0x引用的T&&右值引用这种写法,也可以实现所谓的“通用引用Universal Reference”,从而实现完美转发。
C++从一开始就规定了引用的语义,不过却没有提到“左值”或者“右值”引用,事实上,左值引用正是我们一直以来在C++中使用的引用,过去的C++标准没有规定右值引用,因此过去一直无法使用右值引用。C++0x中规定:右值引用能够通过两个引用符号表示,如果一个函数的参数类型是T&&,那么这个函数就会匹配右值引用参数。使用右值引用时,我们可以确定右值引用对象在函数被调用完成后就会被丢弃,因此可以直接将右值引用对象资源“移动”到this对象中而不用担心这样做会导致右值引用对象的状态遭到破坏(因为之后这个对象就用不到了,会被立即销毁)。
如上所述,使用右值引用时,能够确保右值引用对象会在随后被销毁,因此可以将右值引用对象的资源直接“移动”到当前对象中,“移动”就是指将资源浅拷贝到当前对象,然后将右值引用对象中的资源引用置空。这样,原本由右值引用持有的资源就移动到了当前对象中。这就是移动语义。
C++0x同时在标准库中新增了std::move,move将参数转为右值引用并返回,而forward根据参数是左值还是右值返回对应的引用。

通用引用 & 完美转发

通用引用其实就是右值引用,但是scott mayer认为右值引用不准确,因为有时候“右值引用”引用的其实不是一个右值,因此他坚持使用“通用引用”而不是“右值引用”。
以下列举通用引用的例子:

// 1\. T由编译器进行类型推倒
template <typename T>
void function(T&& t);

// 2\. 使用auto,auto的推导规则其实和范型方法一样,因此也可以被归为上面一类
auto&& t;

完美转发(perfect forwarding)问题是指函数模板在向其他函数传递参数时该如何保留该参数的左右值属性的问题。
也就是说函数模板在向其他函数传递自身形参时,如果相应实参是左值,它就应该被转发为左值;同样如果相应实参是右值,它就应该被转发为右值。
这样做是为了让其他函数能够针对转发而来的参数的左右值属性进行不同处理。
参考上面提到的通用引用的例子1,此时不论T&&被推导为左值引用还是右值引用,实际上的t都会变成左值引用,因为在函数内的参数引用有了名字,能够被引用了,从而不符合右值的定义。但是,编译器会记住t实际上是个右值,如果希望获取t原本的引用类型,就需要使用新增的std::forward方法来获取引用的实际类型。

lambda

auto

auto是自动类型推导,可以根据表达式的返回自动推导出变量的类型。可以使用const & volatile以及引用&指针来修饰auto类型标识。

std::initializer_list

c++11标准库中新增了一个重要的类型定义:

template< class T >
class initializer_list;

一个initializer_list<T>是一个轻量级的代理对象,可以通过它访问一组类型为T的数组。
在以下情况下,initializer_list会被自动创建:

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

推荐阅读更多精彩内容