C++09: A Glimpse into the Future

­­

英文原文: http://www.devsource.com/c/a/Languages/C09-A-Glimpse-into-the-Future/

原作者:Danny Kalev


由于本文包含了大量了英文原文内容,此部分版权由原作者拥有,请勿转载本文,谢谢!


C++09: A Glimpse into the Future

C++09:一览未来

Following the Portland meeting in October 2006, the C++ standardization committee set 2009 as the target date for C++09, the next C++ standard. C++09 will include at least two major core features: rvalue references and type concepts. Other core features are also included, such as automatic deduction of types from initializers, delegating constructors, nullptr, and even a solution to the right angle bracket nuisance. Join me for an overview of core C++09.

200610月波兰大会上,C++标准委员会决定把2009年作为C++09(下一C++标准)的发布时间。C++09将至少包括两个主要的核心特性,右值引用和类型概念。其它核心特性,初始化时类型自动推演,委托构造函数,空指针(nullptr,甚至令人厌烦的右尖号(>)问题的解决方案将一同包括在核心特性里面。让我们一起来C++09核心特性。

C++09: A Glimpse into the Future - ' Rvalue References '

C++09:一览未来之右值引用

C++: the State of the Art

C++技术现状

Today's C++ already provides significant enhancement to C++98. These include subtle technical corrigenda such as vector's contiguity. However, the most important change between C++98 and C++03 is the addition of TR1 libraries which include hashed containers, regular expressions, tuples, new smart pointer classes, and an array class template.

相比C++98,今天的C++已经有了很重要的改进,包括细微的技术勘正,如vector的连续性问题。与C++98相比,C++03最重要的变化是增加了TR1包括hash容器,正则表达式,tuples,一组新的智能指针类以及数组类模板。

A detailed description of TR1 libraries is available here.

TR1库的详细说明可以浏览这里。

TR1-enabled implementations of the Standard Library are already available. TR1 was only the aperitif, though. Core C++ is heading for no less than a revolution.

内含TR1的标准库实现已经问世虽然TR1仅仅是开胃酒,核心C++即将迈向的不亚于一场革命风暴。

Rvalue References

右值引用

C++09 introduces a new category of reference types called rvalue references. Consequently, the traditional reference types that you've been using for decades are now called lvalue references. Unlike lvalue references, rvalue references can bind to rvalues even if they are not const qualified. Rvalue references enable programmers to:

C++09引进一新的引用类型为右型引用,因此我们已使用数十年的传统意义上的引用类型现称为左值引用。有别于左值引用,右值引用可以绑定右值,即使该引用是非const的。使用右值引用可以实现

* Eliminate unnecessary and expensive copies of objects by means of implementing move semantics

* Permit users to implement perfect forwarding, thereby solve major usability problems with generic libraries

* Solve usability problems in components where binding an rvalue to a non-const reference is not a logical error

*通过实现转移语义,消除不必要的和昂贵的对象拷贝。

*允许用户实现完美转发,解决通用库中主要的用性问题。

*解决可用性问题后,把右值绑定到非const引用将不再是逻辑错误。

Before discussing the importance of move semantics, let's look at the syntax of rvalue references. Whereas T& denotes an lvalue reference to T, T&& is an rvalue reference to T. Consider:

讨论右值引用的重要性之前,让我们窥探一下右值引用的语法,这里T&T类型的左值引用,而T&&T类型的右值引用。

void g(int & n);

void h(int&& n);

g(5); //error, 5 is an rvalue

g(int()); //error, temporaries are rvalues

h(5); //OK

h(int()); //OK

S s;

S& rs=s; //ordindary lvalue reference

S&& rrs=S(); //OK, bind a temporary to an rvalue reference

S& illegal = S();//error, bind a temp to an lvalue reference

The Move Movement

C++ has been a copy-semantics language since its inception. Elementary language constructs such as copy constructors, assignment expressions, and argument passing are based on copying an existing object into a new target object. This notion is so fundamental in C++ that it takes time to grasp how significantly different move semantics is. Put simply, moving means constructing the target object directly into the source object. Consequently, you end up having a single object with a new state rather than having two objects that are copies of each other.

C++诞生以来,它一直是拷贝语义的语言。基本的语言结构,如拷贝构造函数,赋值表达式以及参数传递都是基于拷贝现有对象到新的目标对象。C++中这一概念已根深蒂固,理解转移语义本质上的差异,并非瞬间之事。简单来说,转移意味着目标对象直接构造在源对象,最终只存在单个对象,处于新状态,而非两个互为备份的对象。

C++98 already implements move semantics in several places. The Named Return Value Optimization is a manifestation of the move semantics.

C++98某些地方已经实现了转移语义,命名返回值优化就是转移语义的一种表现。

The swap() member function of STL containers also implements move semantics. When you swap two vectors using vector::swap(), the two containers don't copy-construct their elements in new memory destinations; they merely exchange a few pointers and flags. The performance gain can be dramatic. Copying a container of N elements is a linear operation that involves N copy constructor calls + N destructor calls. By contrast, moving is a fast constant time operation.

STL容器类的成员函数swap()同样实现了转移语义。使用vector::swap()函数交换两个vector对象时,两个容器并没有在新内存上使用拷贝构造函数去构建各自的元素;仅仅交换一些指针和标志。赢取的性能是可观的,拷贝N个元素的容器是线性操作,需要调用N次拷贝构造函数和N次析构函数。恰恰相反,对象转移是快速的常数级时间操作。

Another instance of move semantics is the std::auto_ptr class. It has been considered the step child of the Standard Library due to its "peculiar" copy semantics (which is actually pure move semantics!). However, with the advent of rvalue references, it is likely that move-based algorithms and containers will re-enliven the interest in classes such as auto_ptr.

转移语义的另一个实例是std::auto_ptr类,怪异的拷贝语义(事实是纯正的转移语义)使得它常常被看成标准库中的非正统之物。然而,随着右值引用的出现,基于转移的算法和容器会可能会再度勾起大家关注auto_ptr这样的类的兴趣

C++09: A Glimpse into the Future - ' Type Concepts '

C++09:一览未来之类型Concepts

Type Concepts

类型Concepts

Ever since their introduction, C++ templates have suffered from one significant limitation, namely the lack of a mechanism for defining and enforcing constraints on templates. Common workarounds, such as tag dispatching and type traits are inherently complex, verbose and don't guarantee early detection of constraint violations. In some cases, there's simply no way to enforce a constraint at compile time.

自从C++引入模板,它就已经忍受一个重要的缺憾,即缺少某种机制在模板上定义和实施约束。通用的替代品如tag dispatchingtype traits,天生就是复杂的和冗长的,亦不能保证尽早发现违背约束之事。在某些情况下,若要在编译时实施约束,它显得无能为力。

Douglas Gregor and Bjarne Stroustrup's concepts proposal puts an end to this embarrassment. The concepts proposal introduces a separate type-checking system for templates. Template declarations are augmented with a set of requirements known as a concept. When a template is instantiated, the compiler checks whether the instantiation complies with the concept's requirements.

Douglas GregorBjarnet Stroustrupconcepts提案给这尴尬画了句号。该concepts提案给模板引入一种分离的类型测检系统定义模板时加入一组称为concept约束条件,实例化模板时,编译器检查该实例是否满足concept约束条件

Consider the std::min() algorithm:

template<typename T>

const T& min(const T& x, const T& y)

{

return x < y? x : y;

}

The user has to examine the body of min() to know what the requirements from T are. In this case, T must be a type that has an operator< taking two references to T and returning a Boolean result. With concepts, this requirement can be expressed as follows:

用户想知道min函数对类型T有什么要求,唯一的办法就是审查上面的函数体。上例子里,类型T必须提供一个<运算符,要求两个入口参数为T引用型,返回值为Boolean类型。使用concepts可以通过下面方式来表示该要求。

auto concept LessThanComparable

{

bool operator<(T, T);

};

The definition of min() uses this concept as follows:

使用concept后,min函数定义如下:

template<LessThanComparable T> //T must be a LessThanComparable type

const T& min(const T& x, const T& y)

{

return x < y? x : y;

}

Henceforth, whenever the compiler encounters an instantiation of min, it checks whether T meets the LessThanComparable requirements before generating the code for that instantiation. If T isn't LessThanComparable a descriptive error message will be issued.

此后,若编译器遇到min实例,则生成实例代码前检查T是否满足LessThanComparable的约束条件。如果不满足,则输出描述性的错误信息。


Removing Tiny Annoyances from C++

C++09 includes a few core language changes that remove inelegance and minor annoyances.

The angle brackets proposal removes a long standing syntactic displeasure, i.e., the requirement that the right angle brackets of a nested template argument shall be separated with spaces:

尖括号提案删除了一个长期不尽如意的语法问题,那是嵌套模板实参右边的尖括号(两个或多个时)必须以空格隔开。

//C++98

vector <list <int>> vli; //compilation error; >> treated as a right shift operator

vector <list <int> > vli; //OK

The rationale behind this C++98 restriction was the "maximal munch" rule. However, current C++ compilers are smart enough to figure out that the last >> belong to two templates, so there's no reason to burden programmers with this restriction anymore. (It is legal to use spaces in C++09, though.)

C++98这一语法限制背后的根本原因,便是它使用了“贪心”法则。然而现代C++编译并不是傻瓜,它有足够能力分析出最后的>>是属于两个模板的。因此没有理由让程序员去承担这样的语法约束(即使如此,在C++09里使用空格去隔开它们同样合法)。

nullptr is another simple yet welcome addition to C++. Many programming languages have a specific keyword that designates a null pointer or reference. C++ uses the literal 0 for this purpose. This hack causes ambiguity problems, particularly in overload resolution. The proposed nullptr solves this problem:

nullptrC++增加的另一个特性,它简单,更重要是它受欢迎。很多程序设计语言专门用一个关键字分配给空指针或空引用。C++使用字面值0来表示。C++这种方式会引起二义,特别在重载决议时。nullptr提案可以解决此问题。

void f(char *);

void f(int);

f(nullptr); //calls func (char*) because nullptr isn't int

f(0); //calls func(int)

Delegating constructors (also known as forwarding constructors) will make C# and Java newcomers feel at home when using C++09. A delegating constructor uses a member initializer list that invokes another constructor (called the target constructor) of the same class. Once the target constructor returns, the delegating constructor may perform additional operations. This way, common initialization operations are encapsulated in one constructor of the class, instead of being repeated in every constructor:

C++09的委托构造函数(亦称为转发构造函数)会让C#Java程序员使用自如。委托构造函数在成员初始化列表里调用类中另一个构造函数(目标构造函数)。目标构造函数返回后,它可以执行额外的操作。依此,共同的初始化操作只需封装进类中的一个构造函数中,不必遍布在每个构造函数里。

struct S

{

private:

S() {cout<<"target ctor"<<endl;} #1

public:

S(bool b): S() {cout<<"delegating ctor"<<endl;} //invokes target ctor first

};

S obj(false);

The output shows the constructor execution order:

下面的输出显了构造函数的执行顺序:

target ctor

delegating ctor

The Road Ahead

路在前方

Additional C++09 features include, among the rest:

* extern templates (not to be confused with exported templates) which is a mechanism for suppressing the implicit instantiation of templates

* C99 long long type and its unsigned counterpart

* C99 __func__ predefined identifier

* constexpr, a generalized mechanism for treating a function calls as constants

* template aliases: a generalized typedef facility that can be used for templates

* Operator decltype for querying the type of an expression

C++09增加的特性,还包括以下:

extern templates(不要与exported templates混肴)一种限制模板隐式实例化的机制。

*C99 long long类型和它的unsigned类型。

*C99__func__预定义标识符。

*constexpr,一种用于把函数当作常量看待的泛化机制。

*模板别名:一种可用于模板的,泛化的typedef设施。

*操作符decltype,用于获知表达式之类型。

At this stage, it isn't clear yet whether all of these proposals will make it into the next standard. While there is a clear intention to do so, the voting on the Final Candidate Document must take place before the end of 2007 to comply with ISO rules. This leaves the committee two more meetings (in April and October 2007) to finalize the list of C++09 features. C++09 is much closer than it seems!

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页