C++新特性学习

一、C++11新特性

1、auto自动类型推导

1、当类型不为引用时,auto的推导结果将不保留表达式的const属性;当类型为引用时,auto的推导结果将保留表达式的const属性。

2、C++11限制:auto不能在函数的参数中使用,不能作用于类的非静态成员变量,不能作用于模板参数,不能用于推导数组类型。还不能让普通函数具备返回值推导(C++14才行)。

2、decltype右值引用

1、作为操作符,用于查询表达式的数据类型。而auto只能用于返回变量的数据类型。

2、右值引用,也是别名,但其只能对右值引用

cpp 复制代码
//decltype关键字-推导表达式的类型,常用于模板编程
int x = 5;
decltype(x) y = x; // y 是 int
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
	return t + u;
}

3、移动语义 列表初始化 for each等

1、可以将资源从一个对象转移到另一个对象,这样可以减少不必要的临时对象的创建、拷贝及销毁。移动语义与拷贝语义是相对的,可以类比剪切与拷贝。在现有C++机制中,自定义的类要实现转移语义,需要定义移动构造函数,还可以定义转移赋值操作符。

2、左值:有地址、有名字的表达式(如变量)。右值:临时对象、字面量(如函数返回的局部对象),右值引用用&&表示,可以延长临时对象的生命周期。

cpp 复制代码
int x = 10; // x 是左值
int&& r = 20; //20 是右值,r 是右值引用
string getName() {
	string s = "hello";
	return s; //返回局部对象(右值)
}
string&& name = getName(); // 右值引用延长生命周期
//移动构造函数
class StringWrapper {
public:
	//移动构造函数:转移资源,而非复制
	StringWrapper(StringWrapper&& other) noexcept
		: data_(other.data_), size_(other.size_) {
		other.data_ = nullptr; //源对象不再拥有资源
	}
private:
	char* data_;
	size_t size_;
};

//move:将左值转换为右值引用
vector<int> v1 = { 1, 2, 3 };
vector<int> v2 = move(v1);// v1 的资源被转移,v1变为空
//完美转发forward-在模板中保持参数的左值/右值属性
template<typename T>
void wrapper(T&& arg) {
	//完美转发arg给worker,保持其值类别
	worker(forward<T>(arg));
}

4、lambda

实际上是一个匿名类函数。

1、[capture-list]:捕抓列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代表是否为lambda函数,捕抓列表能够捕抓上下文中的变量提供lambda函数使用。

描述了上下文哪些数据可以被lambda使用,以及使用的方式传值还是传引用。

a,\&b\]其中a以复制捕获而b以引用捕获。\[this\]以引用捕获当前对象(\*this)。\[\&\]以引用捕获所有用于lambda体内的自动变量,并以引用捕获当前的对象,若存在。\[=\]以复制捕获所有用于lambda体内的自动变量,并以捕获当前对象,若存在。\[\]不捕获,大部分情况下不捕获就可以了。 2、(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略。 3、mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常变量性,使用该修饰符时,参数列表不可省略(即使参数为空)。mutable放在参数列表和返回值之间。 4、-\>returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。 5、{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。(不能省略)。 ```cpp int main() { //基本语法:[捕获列表](参数列表) -> 返回类型 { 函数体 } vector v = { 1, 2, 3 }; sort(v.begin(), v.end(), [](int a, int b) {return a > b; } ); //捕获外部变量 int base = 10; for_each(v.begin(), v.end(), [base](int n) {cout << n + base << " "; } ); //按值捕获 =,按引用捕获 & auto lambda = [=](int x, int y) {return x + y; }; return 0; } ``` > ### 5、智能指针 > 都是以模板的形式来实现的。使用时,#include\ using namespace std; 1、shared_ptr:和其他两个不同之处在于,多个shared_ptr智能指针可以共同使用同一块堆内存。并且,由于该类型智能指针在实现上采用的是引用计数机制,即便有一个shared_ptr指针放弃了堆内存的shared_ptr指针(只有引用计数为0时,堆内存才会被自动释放)。 2、unique_ptr:指针自然也具备"在合适时机自动释放堆内存空间"的能力。和shared_ptr指针最大不同之处在于,unique_ptr指针指向的堆内存无法同其它unique_ptr共享,也就是说,每个unique_ptr指针都独自拥有对其所指堆内存空间的使用权。 3、weak_ptr:shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维护了一个共享的引用计数器。对于引用计数法实现的计数,总是避免不了循环引用的问题,shared_ptr也不例外。 ```cpp //unique_ptr:独占所有权 unique_ptr p1(new int(5)); //unique_ptr p2 = p1 //错误:不能拷贝 unique_ptr p3 = move(p1);//可以移动 //shared_ptr:共享所有权(引用计数) shared_ptr sp1 = make_shared(10); shared_ptr sp2 = sp1;// 引用计数+1 //weak_ptr:弱引用,解决shared_ptr循环引用问题 class Node { public: shared_ptr next; weak_ptr prev; //弱引用,不增加计数 }; ``` > ### 6、constexpr:编译期计算 > 在编译期执行函数,提高运行效率。 ```cpp constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); } int main() { constexpr int f5 = factorial(5);//编译期计算为120 int arr[f5]; //合法:数组大小需要常量表达式 } ``` > ### 7、并发支持\ > ```cpp void worker() { cout << "Thread ID:" << this_thread::get_id() << endl; } int main() { thread t(worker); t.join();//等待线程结束 //原子操作 atomic counter(0); counter.fetch_add(1); } ``` > ### 8、其他重要特性 > nullptr:类型安全的空指针,替代NULL override/final:明确虚函数重写和禁止重写 =default / =delete:显式控制默认函数 static_assert:编译期断言 哈希表容器:unordered_map/unordered_set 正则表达式库\ 随机表达式库\ 时间库\ ## 二、C++14新特性 > ### 1、泛型Lambda > 允许lambda参数使用auto,让lambda称为模板 ```cpp //C++11:必须指定类型 auto add = [](int a, int b) {return a + b; }; //C++14:泛型lambda auto add2 = [](auto a, auto b) {return a + b; }; ``` > ### 2、Lambda捕获初始化 > 支持用任意表达式初始化捕获变量,实现移动捕获 ```cpp auto ptr = make_unique(10); //C++14:移动捕获 auto lambda = [ptr = move(ptr)]() { return *ptr; }; ``` > ### 3、函数返回类型推导 > ```cpp auto add(int a, int b) { return a + b; } auto getValue() { if (true)return 1;//所有return必须推导为相同类型 else return 2; } ``` > ### 4、decltype(auto) > 结合decltype的推导规则和auto的语法 ```cpp int x = 5; int& y = x; decltype(auto) z = y; // z 是 int& (而不是 int) ``` > ### 5、constexpr增强 > constexpr函数可以包含循环、条件语句等。 ```cpp //C++14允许循环,条件语句 constexpr int factorial(int n) { int result = 1; for (int i = 2; i <= n; ++i) { result *= i; } return result; } ``` > ### 6、标准库新增 > make_unique:创建unique_ptr的工厂函数。shared_timed_mutex:共享互斥体 ## 三、C++17新特性 > ### 1、结构化绑定 > 将结构体、数组、pair/tuple的成员解包到独立变量 ```cpp struct Point { int x, y; }; Point p{ 10, 20 }; auto [x, y] = p; map m = { {1, "one"}, {2, "two"} }; int main() { for (const auto& [key, val] : m) { cout << key << ":" << val << endl; } tuple t = { 42, 3.14, "hello" }; auto [a, b, c] = t; return 0; } ``` > ### 2、if和switch的初始化语句 > 在条件表达式中定义变量,限制作用域。 ```cpp map mp = { {1, "one"}, {2, "two"} }; int main() { //C++17 before auto it = mp.find(1); if (auto it = mp.find(1); it != mp.end()) { //使用it } else { //it仍然可以使用 } //it超出了作用域 return 0; } ``` > ### 3、内联变量 > 解决头文件中定义全局变量的多重定义问题。 ```cpp //头文件中,C++17可以直接定义 inline int global_counter = 0; class MyClass { static inline int instance_count = 0; //类内定义静态成员 }; ``` > ### 4、optional > 表示可能存在或不存在的值,替代特殊值(如-1)表示无效。 ```cpp map mp = { {1, "one"}, {2, "two"} }; optional findValue(const string & key) { if (auto it = mp.find(key); it != mp.end()) return it->second; //返回值 return nullopt; //表示没找到 } int main() { auto result = findValue("key"); if (result.has_value()) { cout << "Found:" << result.value() << endl; } } ``` > ### 5、variant > 类型安全的联合体union,可存储多种类型之一。 ```cpp std::variant v; v = 42; v = 3.14; v = "hello"; // 访问方式:std::visit std::visit([](auto&& arg) { std::cout << arg << '\n'; }, v); ``` > ### 6、string_view > 非拥有的字符串视图,避免拷贝。 ```cpp void process(string_view sv) { //避免了 string 的深拷贝 cout << sv.substr(0, 5); } string s = "very long string"; int main() { process(s); //不拷贝 process("literal"); //直接使用字面量 return 0; } ``` > ### 7、filesystem > 跨平台的文件系统操作库 ```cpp fs::path p = "/home/user/file.txt"; int main() { cout << p.filename() << endl; cout << p.extension() << endl; for (const auto& entry : fs::directory_iterator(".")) { cout << entry.path() << endl; } return 0; } ``` > ### 8、并行STL算法 > 支持多线程并行执行算法。 ```cpp vector v(100000); int main() { sort(execution::par, v.begin(), v.end()); return 0; } ``` > ### 9、折叠表达式 > 简化可变参数模板的展开。 ```cpp template auto sum(Args... args) { return (args + ... + 0);//折叠表达式 } int main() { sum(1, 2, 3, 4);//1 + 2 + 3 + 4 = 10 } ``` > ### 10、if constexpr > 编译期条件判断,只编译符合条件的分支 ```cpp template auto getValue(T t) { if constexpr (is_pointer_v) { return *t; //仅当T是指针时编译 } else { return t; // 仅当T不是指针时编译 } } ``` ## 四、C++20新特性 > ### 1、Concept概念 > 对参数模板参数进行约束,提供更清晰的错误信息\[citation:9\]。 ```cpp #include //定义概念:要求类型T支持加法 template concept Addable = requires(T a, T b) { { a + b } -> same_as; }; //使用概念约束模板参数 template T add(T a, T b) { return a + b; } int main() { add(1, 2); add(1.5, 2.5);//OK //add("hello", "hello"); //错误:不满足Addable概念 } ``` ### 2、范围(Ranges) 更直观、函数式风格的容器操作\[citation:9\]。 ```cpp #include namespace views = views; vector v = { 1, 2, 3, 4, 5, 6 }; //传统写法 vector even; copy_if(v.begin(), v.end(), back_inserter(even), [](int x) {return x % 2 == 0; }); //Ranges 写法:链式调用 auto result = v | views::filter([](int x) {return x % 2 == 0; }) //过滤偶数 | views::transform([](int x) {return x * x; }) //求平方 | views::take(2); //取前两个 ``` ### 3、携程 支持异步编程,可暂停和恢复的函数。 ### 4、三向比较运算符(\<=\>) ```cpp struct Point { int x, y; //自动生成所有比较运算符(==,!=,<,<=,>,>=) auto operator<=>(const Point&)const = default; }; int main() { Point p1{ 1, 2 }, p2{ 1, 3 }; cout << (p1 < p2); //true,因为y比较 return 0; } ``` ### 5、模块(Modules) 替代头文件的现代化编译单元,加快编译速度\[citation:9\]。 ```cpp //math.ixx export module math; export int add(int a, int b) { return a + b; } //main.cpp import math;//不再需要 #include int main() { return add(3, 4); } ``` ### 6、格式化库(format) 类型安全的,类似python的字符串格式化。 ```cpp #include string s = format("Hello, {}! The answer is {}", "world", 42); //s = "Hello, world! The answer is 42" //位置参数 string s2 = format("{1} {0}", "world", "Hello");//"Hello world" ``` ### 7、span 非拥有的连续序列视图,比指针+长度更安全。 ```cpp #include void process(span buffer) { for (int& x : buffer) { x *= 2; } } int main() { vector vec = { 1, 2, 3, 4 }; process(vec);//传递vector int arr[] = { 5, 6, 7, 8 }; process(arr);//传递数组 return 0; } ``` ## 五、C++23 在C++20上做了小幅度改进和改善。 主要特性 expected:带错误信息的返回值类型 mdspan:多维数组视图 print/println:更简洁的输出函数 Ranges库的增强:ranges::to等性新功能 this推导:允许lambda使用显式this参数 stacktrace:栈追踪支持 标准库模块import std:一站式导入标准库

相关推荐
墨染千千秋2 小时前
C/C++ Keywords
c语言·c++
ximu_polaris2 小时前
设计模式(C++)-行为型模式-中介者模式
c++·设计模式·中介者模式
CSCN新手听安3 小时前
【Qt】Qt窗口(八)QFontDialog字体对话框,QInputDialog输入对话框的使用,小结
开发语言·c++·qt
tumu_C4 小时前
用std::function减缓C++模板代码膨胀和编译压力的一个场景
开发语言·c++
Komorebi_99994 小时前
大模型学习day5
学习·大模型
逍遥德4 小时前
AI时代,计算机专业大学生学习指南
java·javascript·人工智能·学习·ai编程
网络与设备以及操作系统学习使用者4 小时前
直连路由优先级最高
运维·网络·学习·华为·智能路由器
Hical615 小时前
C++17 实战心得:那些真正改变我写代码方式的特性
c++
Hical615 小时前
实测:C++20 协程 vs Go Gin vs Rust Actix,谁的 Web 性能更强?
c++