ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【C++进阶】C++ 11(上)

2026/10/1 16:05:19 拓冰建站 浏览量
【C++进阶】C++ 11(上) 目录1 C11 发展历史2 列表初始化统一初始化2.1 C98 时代的{}局限2.2 C11一切对象都可以使用{}列表初始化3 std::initializer_list产生背景上篇小结1 C11 发展历史C11 是 C 第二个主要版本也是自 C98 之后最重要的一次更新。在 2011‑08‑12 被 ISO 正式采纳早期代号叫C0x原本预期 2010 年前完成实际 C03 到 C11 间隔长达 8 年。 自此之后 C 保持大约每 3 年一个版本的迭代节奏表格版本发布年份核心新增代表特性C981998模板、STL 容器算法、string、IO 流C112011移动语义、统一初始化、auto/decltype、lambda、constexpr、多线程、内存模型、正则、智能指针、哈希容器 unordered 系列、std::arrayC142014读写锁、泛型 lambdaC172017折叠表达式、constexpr if、结构化绑定、string_view、STL 并行算法、filesystem、any/optional/variantC202020协程、模块、Concept、Ranges 库C232023deducing this、print 打印库、flat 关联容器、expected、mdspan2 列表初始化统一初始化2.1 C98 时代的{}局限C98 中{}仅仅只支持数组、结构体初始化普通类对象不能直接使用大括号初始化。#includeiostream using namespace std; struct Point { int _x; int _y; }; int main() { int array1[] {1,2,3,4,5}; int array2[5] {0}; Point p {1,2}; // 结构体支持 return 0; }2.2 C11一切对象都可以使用{}列表初始化C11 提出统一列表初始化目标做到一切对象皆可使用{}初始化。内置类型、自定义类对象全部支持可以省略赋值符号底层会先用{...}构造临时对象编译器优化后直接构造目标对象不会发生拷贝向容器push_back / insert传参时{}书写匿名对象非常便捷。#includeiostream #includevector using namespace std; struct Point { int _x; int _y; }; class Date { public: Date(int year 1, int month 1, int day 1) :_year(year),_month(month),_day(day) { cout Date(int year, int month, int day) endl; } Date(const Date d) :_year(d._year),_month(d._month),_day(d._day) { cout Date(const Date d) endl; } private: int _year; int _month; int _day; }; int main() { // C98原有写法 int a1[] {1, 2, 3, 4, 5}; int a2[5] {0}; Point p {1, 2}; // C11列表初始化 int x1 {2}; Date d1 {2025, 1, 1}; // 构造临时对象编译器优化直接构造d1不调用拷贝构造 const Date d2 {2024,7,25}; // 引用绑定临时对象延长生命周期 Date d3 {2025}; Date d4 2025; // 可以省略 Point p1 {1,2}; int x2 {2}; Date d6 {2024,7,25}; const Date d7 {2024,7,25}; vectorDate v; v.push_back(d1); v.push_back(Date(2025,1,1)); // 直接{}传入匿名对象代码更简洁 v.push_back({2025,1,1}); return 0; }3 std::initializer_list产生背景有了{}初始化但是vectorint v {1,2,3,4,5};这种直接用花括号初始化容器依然做不到。 我们希望可以直接传入任意数量参数完成容器构造于是 C11 引入std::initializer_list。std::initializer_listT底层内部保存一个数组仅持有两个指针begin指向数组起始end指向数组末尾支持迭代器遍历。 STL 所有容器都增加接收initializer_list的构造函数与赋值重载才支持{1,2,3}直接初始化。容器原型示意templateclass T class vector { public: vector(initializer_listT il); vector operator(initializer_listT il); // ...其他接口 };示例代码#includeiostream #includevector #includemap using namespace std; int main() { std::initializer_listint mylist {10,20,30}; vectorint v1({1,2,3,4,5}); vectorint v2 {1,2,3,4,5}; const vectorint v3 {1,2,3,4,5}; // map结合pair的{}初始化 mapstring,string dict {{sort,排序},{string,字符串}}; // initializer_list版本赋值 v1 {10,20,30,40,50}; return 0; }重点initializer_list只是代理对象不负责保存数据本体底层数组一般分配在栈上。小结C11 目标统一初始化语法内置类型、自定义类都可以使用{}可以省略。{}会生成临时对象编译器返回值优化 RVO 会消除拷贝。std::initializer_list是容器支持{1,2,3}初始化的底层核心内部只有首尾两个指针。