C++11 能好怎?

0. 摘要

  近期读了一些关于C++11标准的材料。 本篇博客将从新标准的优点、与旧版本的区别和使用方法三个角度,大致介绍我对C++11的认识。

C++11标准,原名C++0x, 是03版旧标准的更新。总结来说,新标准给我更加接近脚本语言的感觉。move语义的支持、auto关键字自动类型等新特性,使得C++11在性能和效率上比旧版本有更大优势。

  我参考的博客和网页有:

  http://www.csdn.net/article/2012-05-15/2805585

  http://*.com/questions/1930903/bind-vs-lambda

  http://baike.baidu.com/link?url=IsEuVplXgGEw6H_tjyGU2pKIKffDw8Sry0aZd9btV8O5upyzGRofxXDviB9RI5C-XYpNY7tzAD9KAZLW8fW4n_

  http://blog.csdn.net/lancelet/article/details/7220558

  http://zh.wikipedia.org/wiki/C++0x

  http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx

  http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx

  http://herbsutter.com/elements-of-modern-c-style/

  http://en.wikipedia.org/wiki/C%2B%2B11

1. C++11 新特性概述

  下面简要介绍对我来说意义较为明显的几点

  1. 右值引用和move语义(move semantics)。它是优化复制的一种方式。在很多时候,深度复制是低效率的行为,而move语义将允许简单的复制指针到字符缓冲区,减少在内存配置上使用的时间。获取右值必须使用std::move<T>().举例:

 bool is_r_value(int &&) { return true; }
bool is_r_value(const int &) { return false; } void test(int && i)
{
is_r_value(i); // i 為具名變數,即使被宣告成右值也不會被認定是右值。
is_r_value(std::move<int&>(i)); // 使用 std::move<T>() 取得右值。
}

  2. 类型推导:auto关键字。auto关键字可以使得我们再也不必根据右值复杂的表达式推断左值的类型。它的意义在于大大增加了代码可读性,并且节省了很多无意义的开发时间,而将数据类型的推测交给编译器来做。

  举例而言,原本我们这样的表达:

 for(vector<int>::const_iterator itr = myvec.begin(); itr != myvec.end();++itr)

  可以简化为:

 for(auto itr = myvec.begin(); itr != myvec.end();++itr)

  decltype可以得到参数实例的数据类型,与auto弥补:

 #include <vector>

 int main()
{
const std::vector<int> v();
auto a = v[];// a 为 int 类型
decltype(v[]) b =; // b 为 const int& 类型,即std::vector<int>::operator[](size_type)const 的返回类型
auto c =; // c 为 int 类型
auto d = c; // d 为 int 类型
decltype(c) e; // e 为 int 类型,c 实体的类型
decltype((c)) f = e; // f 为 int& 类型,因为(c)是左值
decltype() g; // g为int类型,因为0是右值
return ;
}

  3. smart pointer智能指针。智能指针改善了auto_ptr的问题,使得开发过程不必担心内存释放的问题,处理内存泄露的过程得以简化。

  4. 以范围为基础的for循环。for 语句将允许简单的范围迭代:第一部分定义被用来做范围迭代的变量,就像被声明在一般for循环的变量一样,其作用域仅只于循环的范围。而在":"之后的第二区块,代表将被迭代的范围。这样一来,就有了能够允许C-style数组被转换成范围概念的概念图。这可以是std::vector,或是其他符合范围概念的对象。举例:

  原本的表达:

 // circle and shape are user-defined types
circle* p = new circle( );
vector<shape*> v = load_shapes(); for( vector<circle*>::iterator i = v.begin(); i != v.end(); ++i ) {
if( *i && **i == *p )
cout << **i << “ is a match\n”;
} for( vector<circle*>::iterator i = v.begin();
i != v.end(); ++i ) {
delete *i; // not exception safe
} delete p;

  使用新标准,表达相同的过程,可以大大简化:

 #include <memory>
#include <vector>
// ...
// circle and shape are user-defined types
auto p = make_shared<circle>( );
vector<shared_ptr<shape>> v = load_shapes(); for_each( begin(v), end(v), [&]( const shared_ptr<shape>& s ) {
if( s && *s == *p )
cout << *s << " is a match\n";
} );

  5. lambda表达式。lambda表达式允许如下定义:

 [](int x, int y) { return x + y; }

  lambda表达式解决了函数内部不得不使用function对象造成的繁琐问题。

  6. 空指针的调整。在标准C中,0值兼顾了数值和NULL的双重语义,C++并未继承此规则,不允许将void*隐式转换为其他类型的指针。char*c = NULL;这样的表达无法直观的实现。C++11使用nullptr将0和空指针分离开:

 char* pc = nullptr;     // OK
int * pi = nullptr; // OK
int i = nullptr; // error foo(nullptr); // 呼叫 foo(char *)

  7. C++还有其他很有意义的改进,但因笔者目前接触不到这些改进的意义,仅作简单的列举:

  7.1 显示虚函数重载

  7.2 对POD定义的修正

  7.3 强类型的枚举

  7.4 模板别名

  7.5 变长参数模板

  7.6 正则表达式

3. 总结

  C++11,相比于旧版本,主要的提升方面为:1. 语言运行时的表现强化(就是效率更高了) 2. 核心语言使用性加强(就是能写出更简洁的代码) 3. 核心语言能力提升(允许更多的如变长参数模板的表达)

4. 我的问题

  lambda表达式不是很透彻..

  虚函数重载不知道什么时候用?

  其实,我的问题都应该会在新版本的C++Premer中得到解答,这里的疑问只有,在团队编程中,C++11如何与C++03兼容?如果一个项目里面其他的人都使用C++03,或者一个已经写好的程序使用的是C++03,如果做出C++11的改动,能否可行,或者会不会造成问题?

3. 怎么使用?(编译器支持)

  新版本的C++经典教程已经对新标准进行了更新,目前主流编译器对C++11 的支持如下

C++11 Core Language Features

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Rvalue references v0.1, v1.0, v2.0, v2.1, v3.0

v2.0

v2.1*

v2.1*

ref-qualifiers

No

No

No

Non-static data member initializers

No

No

Yes

Variadic templates v0.9, v1.0

No

No

Yes

Initializer lists

No

No

Yes

static_assert

Yes

Yes

Yes

auto v0.9, v1.0

v1.0

v1.0

v1.0

Trailing return types

Yes

Yes

Yes

Lambdas v0.9, v1.0, v1.1

v1.0

v1.1

v1.1

decltype v1.0, v1.1

v1.0

v1.1**

v1.1

Right angle brackets

Yes

Yes

Yes

Default template arguments for function templates

No

No

Yes

Expression SFINAE

No

No

No

Alias templates

No

No

Yes

Extern templates

Yes

Yes

Yes

nullptr

Yes

Yes

Yes

Strongly typed enums

Partial

Yes

Yes

Forward declared enums

No

Yes

Yes

Attributes

No

No

No

constexpr

No

No

No

Alignment

TR1

Partial

Partial

Delegating constructors

No

No

Yes

Inheriting constructors

No

No

No

Explicit conversion operators

No

No

Yes

char16_t/char32_t

No

No

No

Unicode string literals

No

No

No

Raw string literals

No

No

Yes

Universal character names in literals

No

No

No

User-defined literals

No

No

No

Standard-layout and trivial types

No

Yes

Yes

Defaulted and deleted functions

No

No

Yes*

Extended friend declarations

Yes

Yes

Yes

Extended sizeof

No

No

No

Inline namespaces

No

No

No

Unrestricted unions

No

No

No

Local and unnamed types as template arguments

Yes

Yes

Yes

Range-based for-loop

No

Yes

Yes

override and final v0.8, v0.9, v1.0

Partial

Yes

Yes

Minimal GC support

Yes

Yes

Yes

noexcept

No

No

No

C++11 Core Language Features: Concurrency

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Reworded sequence points

N/A

N/A

N/A

Atomics

No

Yes

Yes

Strong compare and exchange

No

Yes

Yes

Bidirectional fences

No

Yes

Yes

Memory model

N/A

N/A

N/A

Data-dependency ordering

No

Yes

Yes

Data-dependency ordering: function annotation

No

No

No

exception_ptr

Yes

Yes

Yes

quick_exit

No

No

No

Atomics in signal handlers

No

No

No

Thread-local storage

Partial

Partial

Partial

Magic statics

No

No

No

C++11 Core Language Features: C99

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

__func__

Partial

Partial

Partial

C99 preprocessor

Partial

Partial

Partial

long long

Yes

Yes

Yes

Extended integer types

N/A

N/A

N/A

上一篇:ExtJs 3 自定义combotree


下一篇:ZooKeeper 安装部署及hello world