C++0x和C++98的区别

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

Changes from the previous version of the standard

基于前一个版本的变化

The modifications for C++ involve both the core language and the standard library.

修订包括内核和标准库

In the development of every utility of the 2011 standard, the committee has applied some directives:

在2011的标准中,委员会做出了如下指示:

  • Maintain stability and compatibility with C++98 and possibly with C;
    维持和C++98的稳定性和兼容性
  • Prefer introduction of new features through the standard library, rather than extending the core language;
    通过添加标准库而非扩展内核的方式添加新特性
  • Prefer changes that can evolve programming technique;
    倾向于那些能够使编程技术发展的变化
  • Improve C++ to facilitate systems and library design, rather than to introduce new features useful only to specific applications;
    发展有用的系统和库的设计,而非针对特定领域优化
  • Increase type safety by providing safer alternatives to earlier unsafe techniques;
    通过新的安全技术增强类型安全
  • Increase performance and the ability to work directly with hardware;
    增强直接和硬件打交道的嵌入式系统的性能
  • Provide proper solutions for real-world problems;
    力图解决真实世界的问题
  • Implement “zero-overhead” principle (additional support required by some utilities must be used only if the utility is used);
    实行“零功耗”准则(只有真正使用的时候才会使用,这个需要意会一下,很难翻译)
  • Make C++ easy to teach and to learn without removing any utility needed by expert programmers.
    傻大空

Attention to beginners is considered important, because they will always compose the majority of computer programmers, and because many beginners would not intend to extend their knowledge of C++, limiting themselves to operate in the aspects of the language in which they are specialized.

Extensions to the C++ core language

One function of the C++ committee is the development of the language core. Areas of the core language that were significantly improved include multithreading support,generic programming support, uniform initialization, and performance enhancements.

提供了多线程支持,泛型编程支持,统一的初始化,以及性能的优化。

For the purposes of this article, core language features and changes are grouped into four general sections: run-time performance enhancements, build-time performance enhancements, usability enhancements, and new functionality. Some features could fall into multiple groups, but they are mentioned only in the group that primarily represents that feature.

核心的语言变化将分为一下四章:

  • 实时性能的增强
  • 编译时间的优化
  • 可用性的优化
  • 以及新的功能
有一些特性可能会在这些章节中重复出现。

Core language runtime performance enhancements

These language features primarily exist to provide some kind of performance benefit, either of memory or of computational speed.

内存和cpu计算时间的优化

Rvalue references and move constructors

“右值引用”和“移动构造器”

In C++03 (and before), temporaries (termed "rvalues", as they often lie on the right side of an assignment) were intended to never be modifiable — just as in C — and were considered to be indistinguishable from const T& types; nevertheless, in some cases, temporaries could have been modified, a behavior that was even considered to be a useful loophole (for the former, see [7]). C++11 adds a new non-const reference type called an rvalue reference,identified by T&&. This refers to temporaries that are permitted to be modified after they are initialized, for the purpose of allowing "move semantics".

A chronic performance problem with C++03 is the costly and unnecessary deep copies that can happen implicitly when objects are passed by value. To illustrate the issue, consider that a std::vector<T> is, internally, a wrapper around a C-style array with a size. If a std::vector<T> temporary is created or returned from a function, it can be stored only by creating a new std::vector<T> and copying all of the rvalue's data into it. Then the temporary and all its memory is destroyed. (For simplicity, this discussion neglects the return value optimization).

In C++11, a "move constructor" of std::vector<T> that takes an rvalue reference to a std::vector<T> can copy the pointer to the internal C-style array out of the rvalue into the new std::vector<T>, then set the pointer inside the rvalue to null. Since the temporary will never again be used, no code will try to access the null pointer, and because the pointer is null, its memory is not deleted when it goes out of scope. Hence, the operation not only forgoes the expense of a deep copy, but is safe and invisible.

Rvalue references can provide performance benefits to existing code without needing to make any changes outside the standard library. The type of the returned value of a function returning a std::vector<T> temporary does not need to be changed explicitly to std::vector<T> && to invoke the move constructor, as temporaries are considered rvalues automatically. (However, if std::vector<T> is a C++03 version without a move constructor, then the copy constructor will be invoked with a const std::vector<T>& as normal, incurring a significant memory allocation.)

For safety reasons, some restrictions are imposed. A named variable will never be considered to be an rvalue even if it is declared as such; in order to get an rvalue, the function template std::move<T>() should be used. Rvalue references can also be modified only under certain circumstances, being intended to be used primarily with move constructors.

Due to the nature of the wording of rvalue references, and to some modification to the wording for lvalue references (regular references), rvalue references allow developers to provide perfect function forwarding. When combined with variadic templates, this ability allows for function templates that can perfectly forward arguments to another function that takes those particular arguments. This is most useful for forwarding constructor parameters, to create factory functions that will automatically call the correct constructor for those particular arguments. This is seen in the emplace_back set of STL methods.

[edit]Generalized constant expressions

C++ has always had the concept of constant expressions. These are expressions such as 3+4 that will always yield the same results, at compile time and at run time. Constant expressions are optimization opportunities for compilers, and compilers frequently execute them at compile time and hardcode the results in the program. Also, there are a number of places where the C++ specification requires the use of constant expressions. Defining an array requires a constant expression, and enumerator values must be constant expressions.

However, constant expressions have always ended whenever a function call or object constructor was encountered. So a piece of code as simple as this is illegal:

int get_five() {return 5;}
 
int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++

This was not legal in C++03, because get_five() + 7 is not a constant expression. A C++03 compiler has no way of knowing if get_five() actually is constant at runtime. In theory, this function could affect a global variable, call other non-runtime constant functions, etc.

C++11 introduced the keyword constexpr, which allows the user to guarantee that a function or object constructor is a compile-time constant [8]. The above example can be rewritten as follows:

constexpr int get_five() {return 5;}
 
int some_value[get_five() + 7]; // Create an array of 12 integers. Legal C++11

This allows the compiler to understand, and verify, that get_five is a compile-time constant.

The use of constexpr on a function imposes some limitations on what that function can do. First, the function must have a non-void return type. Second, the function body cannot declare variables or define new types. Third, the body may contain only declarations, null statements and a single return statement. There must exist argument values such that, after argument substitution, the expression in the return statement produces a constant expression.

Prior to C++11, the values of variables could be used in constant expressions only if the variables are declared const, have an initializer which is a constant expression, and are of integral or enumeration type. C++11 removes the restriction that the variables must be of integral or enumeration type if they are defined with the constexpr keyword:

constexpr double earth_gravitational_acceleration = 9.8;
constexpr double moon_gravitational_acceleration = earth_gravitational_acceleration / 6.0;

Such data variables are implicitly const, and must have an initializer which must be a constant expression.

In order to construct constant expression data values from user-defined types, constructors can also be declared with constexpr. A constexpr constructor's function body can contain only declarations and null statements, and cannot declare variables or define types, as with a constexpr function. There must exist argument values such that, after argument substitution, it initializes the class's members with constant expressions. The destructors for such types must be trivial.

The copy constructor for a type with any constexpr constructors should usually also be defined as a constexpr constructor, in order to allow them to be returned by value from a constexpr function. Any member function of a class, such as copy constructors, operator overloads, etc., can be declared as constexpr, so long as they meet the requirements for constexpr functions. This allows the compiler to copy classes at compile time, perform operations on them, etc.

If a constexpr function or constructor is called with arguments which aren't constant expressions, the call behaves as if the function were not constexpr, and the resulting value is not a constant expression. Likewise, if the expression in the return statement of a constexpr function does not evaluate to a constant expression for a particular invocation, the result is not a constant expression.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值