1. 关键字和语法
1.1 nullptr
空指针,能够和整数0进行区别,因为#define NULL 0
1.2 类中非静态成员变量定义时初始化 & 初始化列表
// 1. 一般变量、数组的定义
int a = 10;
int b[] = { 1, 2, 3 };
// 2. C++ 11变量、数组的定义
int c{10};
int d = { 10 };
int e[] { 1, 2, 3 };
// 区别
int abc = 3.5f; // 被截断,丢失精度
int abc1 { 3.5f }; // 编译不通过
1.3 auto
可推导出右值类型,从而得知左边变量类型。发生在编译阶段。
简单使用示例:
auto func() {
return 3.33;
}
struct Test {
int a;
double c;
};
void test() {
auto a = 1;
auto b = func();
cout << b << endl;
Test t1 = { 2,2.111 };
auto t2 = t1;
cout << typeid(t2).name() << endl; // struct Test
}
注意:
(a)auto定义变量必须初始化,如下用法错误;
auto a;
a = 10;
(b)auto不能定义自定义类型的成员变量,如下用法错误;
struct Test {
int a;
auto b = 10;
}
(c)auto不能定义数组,如下用法错误;
auto b[3] = { 1, 2, 3 };
(d) auto不能作为模板实例化类型,如下用法错误;
vector<auto> v = { 1, 2, 3 };
1.4 decltype
获取变量的类型。
简单使用示例:
auto c = 3.3;
decltype(c) d = 9.9;
cout << typeid(d).name() << endl; // double
cout << d << endl; // 9.9
/*获取枚举类型*/
enum { OK, ERROR } flag;
decltype(flag) flag2;
类型追踪:
结合模板和auto使用。
template<typename T1, typename T2>
auto add(const T1&& a, const T2&& b)->decltype(a + b) { // 推导出(a+b)类型
return a + b;
}
void test01() {
auto ret1 = add(1, 1.01);
cout << typeid(ret1).name() << endl; // double
auto ret2 = add(1, 2);
cout << typeid(ret2).name() << endl; // int
}
1.5 基于范围的for循环
可遍历数组、容器等,底层为指针或迭代器实现。
for(Type val : container) {
cout << val << endl;
}
注意:
范围需确定,否则无法使用,如下用法错误:
void func(int a[]) {
for(int& tmp:a) {
cout << tmp << endl;
}
}
1.6 静态断言
断言:运行时检查条件,为真则继续执行,否则终止程序,提示错误。如下:
#include<cassert>
void test04() {
bool flag = false;
assert(flag == true);
cout << "Hello!" << endl; // 不执行
}
运行结果:
静态断言:编译时检查条件。
用法:
static_assert(常量表达式条件, "提示字符串");
例如:
void test05() {
static_assert(sizeof(void*) == 4, "64位!"); // 静态断言失败
cout << "Hello" << endl;
}
1.7 noexcept修饰符
声明一个函数不会抛出异常,帮助编译器优化代码,使用方式如下:
void test06() noexcept {
...
}
1.8 模板的默认参数
如下:
/*普通函数 一默到底*/
void test07(int a, int b = 3, int c = 5) {
}
/*类模板 一默到底*/
template<typename T1, typename T2 = double>
class A {
};
/*类模板 无限制*/
template<typename T1 = int, typename T2, typename T3>
auto test08(T1 a, T2 b, T3 c)->decltype(a + b + c) {
return a + b + c;
}
1.9 可变参模板
typename... A
(1)可变参模板函数递归方式展开参数包
void debug() { // 递归终止函数示例
cout << "调用结束.\n" << endl;
}
template<typename T1, typename...T2>
void debug(T1 first, T2...args) {
cout << first << endl;
// 递归调用
debug(args...);
}
void test07() {
debug(1, "ABC", 3.14159);
}
运行结果:
(2)可变参模板非递归方式展开参数包
template<typename T>
void print(T tmp) {
cout << tmp << endl;
}
template<typename...T>
void expand(T...args) {
// 逗号运算符
// 初始化列表
int a[] = { (print(args),0)... };
}
void test08() {
expand(1, 2, 3, 4);
}
运行结果:
(3)模板类继承方式展开参数包
待补充.
1.10 右值引用
省去内存开辟、拷贝构造等。包括move移动语义函数、forward类型完美转发。
1.11 后置返回值类型
void func(int a) { // 前置返回值类型
}
auto func(int a) -> void { // 后置返回值类型
}
auto func(int a) -> void; // 函数声明
1.12 虚函数相关
(1)override关键字
建议在派生类虚函数后加关键字override,避免虚函数名、返回值类型、参数列表写错。
virtual void func() override {
cout << "Derive::func()" << endl;
}
(2)final关键字
final修饰基类中的虚函数,禁止在派生类中重写。
/*基类中的虚函数*/
virtual void func() final {
cout << "Base::func()" << endl;
}
2. 绑定器和函数对象
bind、function、Lambda表达式
3. 智能指针
shared_ptr、weak_ptr
4. 容器
set、map:红黑树,数据有序,O(logn);
unordered_set、unordered_map:哈希表,不要求数据有序,O(1);
array:不可扩容数组;
forward_list:前向链表;list:双向链表。
5. 语言级别的线程库
使得多线程程序可更好地跨平台。
thread、mutex、condition_variable
lock_guard、unique_lock
atomic原子类型
sleep_for文章来源:https://www.toymoban.com/news/detail-449902.html
底层封装的仍是Windows、Linux的线程API,例如Linux下可使用strace ./a.out跟踪程序的调用。文章来源地址https://www.toymoban.com/news/detail-449902.html
到了这里,关于C++11 部分新特性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!