《Eigen入门》第 15 章 · 现代 C++ 特性
发布时间:2026/10/18 5:18:31 锦皓数字建站

C 从 2011 年开始进入现代 C时代C11、14、17…新增了许多让代码更简洁、更安全、更高效的特性。本章讲几个最常用的auto、范围 for、lambda、nullptr 等。15.1 auto自动推导类型写类型名很繁琐时让编译器帮你推导intx42;// 手动写类型autoy42;// auto 自动推导为 intstd::vectorintv{1,2,3};std::vectorint::iterator itv.begin();// 好长的类型autoit2v.begin();// auto 简洁得多auto让编译器根据右边的值自动推断类型特别适合类型名很长的场景如 Eigen 的某些类型。遍历容器时配合 autofor(autoitv.begin();it!v.end();it){...}// 迭代器遍历for(autox:v){...}// 范围 for15.2 范围 forrange-for第 12 章提过这里再强调因为它太常用std::vectorintv{1,2,3,4,5};for(intx:v){std::coutx ;}// 只读for(intx:v){x*2;}// 引用可修改for(constautox:v){std::coutx ;}// 常量引用只读高效for (元素 : 容器)自动遍历容器每个元素不用写下标、不用关心边界。15.3 lambda 表达式匿名函数lambda 是没有名字的函数可以定义在使用它的地方#includeiostreamintsquare(intx){returnx*x;}// 普通函数autosquareLambda[](intx){returnx*x;};// 等价的 lambdaintmain(){std::coutsquare(5) squareLambda(5)std::endl;// 25 25return0;}注意这里 lambda 换了个名字。如果你写成auto square …会和上面那个函数重名编译器报auto square redeclared as different kind of entity——同一个作用域里函数和变量不能共用一个名字。语法[捕获](参数) { 函数体 }[]捕获列表访问外部变量()参数{}函数体lambda 最常用于配合标准库算法#includealgorithm#includevector#includeiostreamintmain(){std::vectorintv{5,2,8,1,9};// 用 lambda 做排序规则降序std::sort(v.begin(),v.end(),[](inta,intb){returnab;});for(intx:v)std::coutx ;// 9 8 5 2 1}std::sort是标准库排序算法第三个参数是比较规则lambda 直接内联写出来非常方便。捕获外部变量intthreshold5;autoisBig[threshold](intx){returnxthreshold;};// 捕获 threshold 的值[threshold]表示按值捕获外部变量thresholdlambda 内就能用它。15.4 nullptr明确的空指针以前用NULL其实是 0现在用nullptr类型更明确int*pnullptr;// 明确的空指针if(pnullptr){...}15.5 统一初始化{}花括号初始化更安全禁止窄化转换inta{5};// 花括号初始化std::vectorintv{1,2,3};Point p{1.0,2.0};// 类也能用15.6 常用现代写法总结// 老写法先建空容器再逐个追加std::vectorintoldWay;oldWay.push_back(1);// 现代写法一行建好并给初值std::vectorintv{1,2,3};// 老写法下标遍历for(std::size_t i0;iv.size();i){std::coutv[i] ;}// 现代写法范围 forfor(autox:v){std::coutx ;}循环变量的类型v.size()返回的不是int而是无符号的std::size_t。写成for (int i 0; i v.size(); i)加-Wall编译会出警告comparison of integer expressions of different signedness更麻烦的是将来出现v.size() - 1这类式子时空容器的结果会变成一个巨大的正数。要么老老实实写std::size_t要么直接用范围 for推荐。15.7 一个贯穿全部特性的示例#includeiostream#includevector#includealgorithmintmain(){// auto 初始化列表autoscoresstd::vectorint{85,92,78,60,95,88};// 范围 for 遍历std::cout原始分数;for(autos:scores)std::couts ;std::coutstd::endl;// lambda 算法统计及格人数intpassstd::count_if(scores.begin(),scores.end(),[](ints){returns60;});std::cout及格人数passstd::endl;// lambda求平均分doublesum0;for(autos:scores)sums;std::cout平均分sum/scores.size()std::endl;return0;}实际输出原始分数85 92 78 60 95 88 及格人数6 平均分83六个分数都 ≥ 60所以及格人数是 6平均分 498 / 6 83。这二十几行里同时出现了auto、范围 for、lambda、标准库算法——现代 C 的日常写法就是这么组合的。15.8 小结auto自动推导类型适合长类型名。范围 for简洁遍历容器。lambda匿名函数[](参数){函数体}配合算法好用。nullptr明确的空指针。{}统一初始化。 第一部分完成恭喜你学完了 C 的基础你现在已经掌握了变量、类型、运算符、控制流、函数数组、字符串、指针、引用、类动态内存、智能指针、STL 容器重载、模板、现代 C 特性这些是写任何 C 程序的基础。第二部分我们补上理解 Eigen 所需的线性代数然后进入 Eigen 的正题。练习题用auto声明一个std::vectorint用范围 for 遍历打印。用 lambda 配合std::sort给一个 vector 降序排序。用 lambda 判断一个数是否为偶数配合std::count_if统计偶数个数。用{}初始化一个字符串和一个 vector。用自己的话总结auto、范围 for、lambda 分别解决什么问题。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。