上周5 听了C++11 的一次介绍讲座, 这里就随便吐槽一下.
C++11, 2011年4月通过ISO appoved的一个C++标准. 当第一次听到这个标准的时候, 我有点迷惑, 因为虽然我现在对这个语言不再感冒, 但毕竟曾经在它身上耗费了不少的光阴, 如同相恋多年最终还是无奈分手的恋人, 时不时还是会关心一下, 而却几乎没有注意到这么一个标准. 众所周知, ISO 要通过某个标准的过程是异常漫长的…
google了一下才知道, 原来这个标准就是之前的C++0x, 太坑爹了, 据说是为了和以前的命名规则一致, 于是改名叫C++11. 小样, 换了个马甲就不认得你啦?
不过这次C++11 确实是这帮老人家们费尽脑汁想出来的一个非常革命性的C++版本. 甚至连C++之父, Bjame Stroustrup 童鞋也不禁要说, C++11 就像一个新的语言. 那么在吐槽之前, 先简单看看这次都加了什么相对比较"强大"的功能. 小的就不提了, 而且我也不了解, 想知道的去看标准文档吧: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372 一如既往, 这标准的pdf文档份量十足, 12Mb多, 怎么看怎么吐血… 记得刚毕业的时候, 年少无知的我还曾经打印过一本, 足足牛顿高阶字典一般的厚度, 拿在手上有无比的满足感, 可看的时候就怂了…
lambda表达式
[capture](parameters)->return-type {body}
[]里是函数调用的参数列表,表示一个Lambda表达式的开始,让我们来看一个Lambda例子:
假设你想计算某个字符串包含多少个大写字母,使用for_each()遍历一个char数组,下面的Lambda表达式确定每个字母是否是大写字母,每当它发现一个大写字母,Lambda表达式给Uppercase加1,Uppercase是定义在Lambda表达式外的一个变量:
for_each(s, s+sizeof(s), [&Uppercase] (char c) {
if (isupper(c))
Uppercase++;
});
auto和decltype
在C++03中,在声明对象时,你必须指定对象的类型,然而,在许多情况下,对象的声明包括在初始化代码中,C++11利用了这个优势,允许你声明对象时不指定类型:
auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long
相反,你可以声明下面这样的迭代器:
void fucn(const vector<int> &vi)
{
auto ci=vi.begin();
}
也可以使用decltype 关键字来推断返回值类型而用于声明中:
const vector<int> vi;
typedef decltype (vi.begin()) CIT;
CIT another_const_iterator;
Delete 和 Default 关键字
C++11 加入了delete关键字, 比如我们知道编译器一般都会为每个类对象生成一些默认的函数, 比如默认构造函数, 默认析构函数, 默认赋值函数等, 而在我们不希望编译器为我们生成这样的函数的时候, 可以使用delete这个关键字给这些函数"赋值", 例如:
struct NoCopy
{
NoCopy & operator =( const NoCopy & ) = delete;
NoCopy ( const NoCopy & ) = delete;
};
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted
而default 则恰好相反, 如果需要默认函数的时候, 就可以把该函数赋值default, 比如默认构造和析构函数.
其他
C++11的新特性还包括了真正意义上的空指针, 委托构造函数, 右值引用, 统一初始化构造等等新的特性. 这里就不一一描述了, 网上描写很多, 就不一一举例.
吐槽
我必须先承认, 我是anti-cpp的, 所以观点不保证任何公平性, 自问多少有点偏见. 不同意的童鞋也欢迎尽管吐槽 =)
对于这次C++11 的推出, 有人很乐观, 觉得是老树焕新芽, 可以救C++ 一命, 因为随着C++使用者的不断减少, 以及脚本语言的兴起, 这门语言已经越来越式微, 离开市场也许指日可待, 成为一个教科书上的语言.
而我觉得这次的11标准也许是它的回光返照. 因为对于这几个比较多人关注的新语法特性, 我有一些看法:
- 确实, 引入了lambda 对于程序的结构会有很大的改变, 一些代码可以被嵌入到另一堆的代码当中去. 但这样的写法是否优雅呢? 我持保留态度. 而且这个[] 的关键字也是非常的蛋痛, 特别是比如你看到这样的一个表达式, [](){}() , 我想不抓狂的人应该属于少数吧?
- auto是个很方便的特性, decltype 看上去也很美. 不过试想一下这样的一个场景:
{
auto i = foo();
shot(i);
}
那么这个shot的编写者可能就会开始郁闷了, i的类型是不定的, 那么我要写什么样的函数呢? 因为声明中是不能有auto的, 所以还是需要为每个i的类型写函数, 或者用范式? 明明是一个强类型的语言, 为何要装纯想减弱这个强类型呢? 多少有点不伦不类了…
不过, 这个功能也是唯一一个我觉得会被广泛使用的功能, 因为确实在处理iterator的时候方便好多, 因为每次写iterator的类型的时候都很让人抓狂… btw, for_each 的引入也是不错的一个功能.
- delete 和default 就更加蛋痛的功能了. 类似的功能在03标准中就已经可以比较好的方式实现, 用了这两个关键字之后就显得有点蛋痛, 而且除了对编译器能生成的函数以外, default是没有其他用途的, 比如Car 类有个函数叫ChangeTire, 它是无论如何都没法default的. 唯一换来的好处可能是让看头文件的人更加清楚, 那些默认行为没有了, 也能省下来一点点的编译时间和编译后size(??)
- 至于右值引用我就觉得更蛋痛了. 这个功能我坦白我没非常了解它的正确用法, 在讲解会上也没有听的很明白, 本来晦涩的特性在C++里面已经不算新鲜了, 这次又引入那么一个, 那么可想而知这个功能如果使用起来会引入多少bug…
- 编译器的支持将会是这个标准被废掉的另一个原因. 这次的更新很强大, 甚至连Bjame 都觉得不认识它了. 但是这些功能对于编译器开发者来说估计是个噩梦, 支持单一的功能也许不麻烦, 但是在支持的基础上编译器还要能够编译03版本的C++程序, 做到兼容估计需要不短的时间, 据说gcc和vc 都已经支持了一部分, 但在短期内没有全面支持C++11 的打算. 如果没有编译器的支持, 这个标准只能作为一纸空文了.
不得不承认, C++11 的制定者们还是很有想法的, 也不愧是牛人, 为了挽救这门语言, 他们费尽心思, 想让它焕发青春. 不过从我的角度, 这次的修改没有能够改变我对它的看法. 依然的高高在上, 依然的语法晦涩. C++活下去是一点问题没有的, 单单是全球的大学就可以让它活下去并且活得不错. 但这次修改我认为是没法让它恢复年轻的.
正如最近看完了7本的<明朝那些事儿>, 在明末的描述中, 不断的提到一个词: 气数已尽. 确实如此, 每个物体都是有生命周期的, 人会死, 植物会枯萎, 没有事物是永恒的, 不过我不是算命先生, C++ 气数如何我无从得知, 但它已经青春不再应该无容置疑了. 一厢情愿的想返老还童不太现实, 还不如趁此机会把优势发扬光大, 而不是一天黑路走到底, 更好….