C++2.0新特性
C++2.0新特性包括语言和标准库两个层面。
视频学习:侯捷老师 《C++2.0新特性》
标准库层面以header files(头文件)形式体现
C++标准库的header files不带副档名(.h),例如#include<vector>
新式C header files不带副名称.h,例如#include<cstdio>
旧式C header files(带有副名称.h)仍可用,例如#include<stdio.h>
标准库都放在命名空间std里面 ,使用标准库要么使用using namespace std或者std::
DevC++ 上的 ISO C++11 开关
Project -> Project Options -> Compiler -> Code Generation -> Language standard(-std)->选择 ISO C++11
资源网站
GCC, the GNU Compiler Collection - GNU Project
确认支持C++11:macro __cplusplus
1 | std::cout<<__cplusplus; |
输出199711则不支持C++11,输出201103及以上则支持C++11
Variadic Templates(数量不定的模板参数)
1 | void print() // 无参数时调用,必须有 |
**…**就是一个所谓的pack(包)
用于 template parameters,就是 template parameters pack(模板参数包)
用于 function parameter types,就是 function parameter types pack(函数参数类型包)
用于 function parameters,就是 function parameters pack(函数参数包)
1 | print(7.5, "hello", bitset<16>(377), 42); |
1 | // 与上面那个可以并存 |
nullptr and std::nullptr_t(空指针)
C++11 lets you use nullptr instead of 0 or NULL
nullptr has type std::nullptr_t, defined in <cstddef>
Automatic Type Deduction with auto(自动类型推导)
With C++11, you can declare a variable or an object without specifying its specific type by using auto
Using auto is especially usefull where the type is a pretty long and/or complicated expression.
1 | vector<string> v; |
Uniform Initialization(统一初始化/一致性初始化)
变量名后面加大括号{}
1 | int values[]{1,2,3}; |
编译器看到 {t1,t2…tn} 便做出一个initializer_list<T>(T为 t1,t2…tn 类型),它关联至一个array<T,n>。调用函数(例如ctor)时该array内的元素可被编译器分解逐一赋给函数。但若函数参数是个initializer_list<T>,调用者却不能给予数个T参数然后以为它们会被自动转为一个**initializer_list<T>**传入。
Initializer Lists(初始化列表)
An initializer list forces so-called value initialization, which means that even local variables of fundamental data types, which usually have an undefined initial value, are initialized by zero (or nullptr, if it is a pointer)
1 | int i; // i has undefined value |
narrowing initializations——those that reduce precision or where the supplied value gets modified——are not possible with braces.
1 | int x1(5.3); // OK, but OUCH: x1 becomes 5 |
initializer_list<>
std::initializer_list<> can be used to support initializations by a list of values or in any other place where you want to process just a list of values
1 | void print(std::initializer_list<int> vals) // 传给initializer_list者,一定是个initializer_list( or{...}形式) |
initializer_list类源代码中,编译器会准备好array来调用私有的构造函数
The initializer_list object refers to the elements of this array without containing them
Copying an initializer_list object produces another object referring to the same underlying elements, not to new copies of them (reference semantics/引用语义).
如今所有容器都接受指定任意数量的值用于建构或赋值或 insert() 或 assign() ; max() 和 min() 也愿意接受任意参数
1 | cout << max( {string("Ace"), string("Stacy"), string("Sabrina"), string("Barkley")} ); // Stacy |
explicit for ctors taking more than one argument
禁止隐式转换
1 | class P |
range-based for statement(基本范围的for循环)
1 | for(decl : coll){ // 把coll中的元素一个个取出来赋值给decl |
1 | vector<double> vec; |
no explicit type conversions are possible when elements are initialized as decl inside the for loop.(允许隐式转换)
1 | class C |
=default, =delete
如果你自行定义了一个ctor,那么编译器就不会再给你一个 default ctor
如果你强制加上 =default,就可以重新获得并使用 default ctor
1 | class Zoo |
Big-Three:拷贝构造函数,赋值构造函数,析构函数
Big-Five:拷贝构造函数,赋值构造函数,析构函数,移动构造函数,移动赋值函数
=default; 用于Big-Five之外无意义,编译报错
=delete; 可用于任何函数身上(=0只能用于 virtual 函数)
1 | class Foo |
Private-Copy
1 | class PrivateCopy{ |
此class不允许被 ordinary user code copy, 但仍可被 friends 和 members copy。若欲完全禁止,不但必须把 copy controls 放到 private 内且不可定义之
Alias Template (template typedef)(别名模板)
1 | template <typename T> |
It is not possible to partially or explicitly specialize an alias template(别名模板不能显式特化或偏特化)
1 | // 使用macro(宏)无法达到相同效果 |
采用 function template + iterator + traits来实现向函数传入容器类型和容器中存储的类型
template语法在模板接受一个template参数Container时,当Container本身又是个class template,能取出Container的template参数
例如收到一个vector<string>,能够取出其元素类型string
1 | template<typename T> |
template template parameter(模板模板参数)
Alias templates are never deduced by template argument deduction when deducing a template template parameter
无法进行模板模板参数推导
1 | template<typename T,template<class> class Container> |
Type Alias (similar to typedef)
There is no difference between a type alias declaration and typedef declaration. This declaration may appear in block scope, class scope, or namespace scope.
1 | typedef void (*func)(int, int); |
一些关键字
noexcept(保证函数不抛异常)
1 | void foo() noexcept; |
declares that foo() won’t throw. If an exception is not handled locally inside foo()——thus, if foo() throws——the program is terminated, calling std::terminate(), which by default calls std::abort()(函数抛出异常,调用该函数的函数不处理,异常会抛向调用该函数的函数的函数,若仍未处理,继续向上抛出,若一直未处理,到main函数(未处理异常)时将会调用abort函数结束程序)
You can even specify a condition under which a function throws no exception. For example, for any type Type, the global swap() usually is defined as follows: (可以限制一个条件,在该条件下,函数一定不会抛出异常)
1 | void swap(Type& x,Type& y) noexcept(noexcept(x.swap(y))) // 该函数不抛出异常条件是x.swap(y)不抛出异常 |
Here, inside noexcept(…) , you can specify a Boolean condition under which no exception gets thrown: Specifying noexcept without condition is a short form of specifying noexcept(true)
You need to inform C++ (specifically std::vector) that your move constructor and destructor does not throw. Then the move constructor will be called when the vector grows. If the constructor is not noexcept, std::vector can’t use it, since then it can’t ensure the exception guarantees demanded by the standard
growable containers(会发生 memory reallocation)只有两种:vector 和 deque
1 | class MyString{ |
using
using-directives for namespaces and using-declarations for namespace members
引入命名空间和引入命名空间中的成员,引入后,当前作用域内,使用不需要带命名空间前缀
1 | using namespace std; |
using-declarations for class members
引入类成员,引入后,当前作用域内,使用不需要带类前缀
1 | using _Base::_M_impl; |
type alias and alias template declaration (since C++11)
类型别名和别名模板
1 | using func = void(*)(int,int); |
override
重写虚函数,接在要重写的函数后,未进行重写将报错
1 | struct Base{ |
final
禁用继承,使用在类后,表示当前类是最后一个,无法被继承,若继承将会报错
1 | struct Base1 final {}; |
禁用重写,使用在虚函数后,继承该类的类无法重写该函数
1 | struct Base2{ |
decltype ( defines a type equivalent to the type of an expression )
decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导。
One application of decltype is to declare return types. Another is to use it in metaprogramming or to pass the type of a lambda(decltype应用有声明返回类型和用于元编程,或者传递lambda表达式类型)
decltype, used to declare return types
With C++11, you can alternatively declare the return type of a function behind the parameter list
1 | template<typename T1,typename T2> |
decltype, used to pass the type of a lambda
面对 lambda ,我们手上往往只有 object ,没有 type
要获得其 type 就得借助于 decltype
1 | auto cmp =[](const Person& p1,const Person& p2){ |
Lambdas
C++11 introduced lambdas, allowing the definition of inline functionality, which cna be used as a parameter or a local objecct. Lambdas change the way the C++ standard library is used
A lambda is a definition of functionality that can be defined inside statements and expressions
Thus, you can use a lambda as an inline function. The minimal lambda function has no parameters and simply does something
$$
…mutable_{opt} throwSpec_{opt} -> retType_{opt} {…}
$$
1 | [] { |
You can call it directly
1 | [] { |
or pass it to objects to get called
1 | auto l = [] { |
$$
…mutable_{opt} throwSpec_{opt} -> retType_{opt} {…}
$$
[…] lambda introducer capture to access nonstatic outside objects inside the lambda. Static objects such as std::cout can be used
opt下标的 All of them are optional, but if one of them occurs, the parentheses for the parameters ( (…) ) are mandatory(强制的)
mutable objects are passed by value, but inside the function object defined by the lambda, you have write access to the passed value
retType Without any specific definition of the return type, it is deduced from the return value
You can specify a capture to access data of outer scope that is not passed as an argument
[=] means that the outer scope is passed to the lambda by value
[&] means that the outer scope is passed to the lambda by reference
1 | int x=0; |
1 | int id=0; |
The type of a lambda is an anonymous function object (or functor)
1 | // 上面类似于下面 |
1 | int id=0; |
C++ Keywords
- Titre: C++2.0新特性
- Auteur: tiny_star
- Créé à : 2025-08-01 14:01:54
- Mis à jour à : 2025-10-17 12:49:20
- Lien: https://tiny-star3.github.io/2025/08/01/Cpp/C++2.0新特性/
- Licence: Cette œuvre est sous licence CC BY-NC-SA 4.0.