C++进阶:C++11(2)
◆博主名称少司府欢迎来到少司府的博客☆*: .. o(≧▽≦)o ..:*☆⭐数据结构系列个人专栏初阶数据结构_少司府的博客-CSDN博客⭐C基础个人专栏C初阶_少司府的博客-CSDN博客⭐琢玉成器终有时笔底生花夺锦归目录1. 可变模板参数1.1 基本语法1.2 包扩展2. 移动构造和移动赋值2.1 概念2.2 实现3. emplace系列接口4. 新的类功能4.1 默认的移动构造和移动赋值4.2 成员变量声明时给缺省值4.3 defult和delete4.4 final和override5. lambda表达式5.1 lambda表达式基本语法5.2 捕捉列表5.3 lambda的应用6. 包装器6.1 function6.2 bind1. 可变模板参数1.1 基本语法C11支持可变参数模板即支持参数数量可变的函数模板和类模板。可变数目的参数被称为参数包分为函数参数包和模板参数包表示0或多个函数参数/模板参数。我们用省略号来指出一个模板参数或函数参数表示一个包。在模板参数列表中class...或typename...指出接下来表示0或者多个类型列表在函数参数列表中类型名后面跟...指出接下来表示0或者多个形参对象列表函数参数包可以左值引用或者右值引用表示遵守引用折叠的规则。namespace test_01 { // 可变模板参数 templateclass ...Args // 0到n个参数 void Print(Args... args) { cout sizeof...(args) endl; // sizeof...计算参数包内有几个参数 } }这里我们可以用运算符 sizeof... 来计算参数包里面有几个参数1.2 包扩展对于一个参数包我们除了能计算它的参数个数还能扩展它。namespace test_02 { // 包扩展(解析出参数包的内容) void ShowList() { // 编译时递归的终止条件参数包是0个时直接匹配这个函数 cout endl; } template class T, class ...Args void ShowList(T x, Args... args) { // 运行时逻辑不行包展开是编译时逻辑 //if (sizeof...(args) 0) // return; cout x ; // args是N个参数的参数包 // 调用ShowList参数包的第一个传给x剩下N-1个传给第二个参数包 ShowList(args...); } template class ...Args void Print(Args... args) { ShowList(args...); } }当然我们也可以这样获取参数包namespace test_03 { template class T const T GetArg(const T x) { cout x ; return x; } template class ...Args void Arguments(Args... args) { } template class ...Args void Print(Args... args) { // 注意GetArg必须返回或者得到对象这样才能组成参数包给Arguments Arguments(GetArg(args)...); // 实参求值顺序未定义C 包展开表达式求值顺序未规定 } }2. 移动构造和移动赋值2.1 概念移动构造函数是一种构造函数类似于拷贝构造要求第一个参数是该类类型的右值引用若还有其他参数必须给出缺省值移动赋值是一个赋值运算符重载和拷贝赋值构成函数重载要求第一个参数是该类类型的右值引用。2.2 实现// 移动构造 string(string s) { cout string(string s) -- 移动构造 endl; swap(s); } // 移动赋值 string operator(string s) { cout string operator(string s) -- 移动赋值 endl; swap(s); return *this; }对于string/vector这样深拷贝的类或者包含深拷贝的成员变量的类移动构造和移动赋值才有意义其本质就是窃取右值对象的资源不用一个一个地去拷贝提高效率。3. emplace系列接口C11以后STL容器新增了emplace系列接口该系列接口均为模板可变参数功能上兼容push和insert系列并且假设容器containerTemplace支持直接插入构造T对象的参数在有些场景下会更高效些。void Test() { listrmove::string lt; // 传左值跟push_back一样走拷贝构造 rmove::string s1(1111111111); rmove::string s2(1111111111); lt.emplace_back(s1); cout ****************** endl; lt.push_back(s2); cout ****************** endl; cout endl; // 传右值,跟push_back一样走移动构造 lt.emplace_back(move(s1)); cout ****************** endl; lt.push_back(move(s2)); cout ****************** endl; cout endl; // 直接传参隐式类型转换 lt.emplace_back(111111111); // 没有隐式类型转换直接构造 cout ****************** endl; lt.push_back(111111111); // 有隐式类型转换需要临时对象深拷贝构造移动构造对于浅拷贝的类型就是构造拷贝构造 cout ****************** endl; }第二个不同void Test_02() { listpairstring, int lt1; // lt1.emplace_back({苹果, 1}); 不能这样写 lt1.emplace_back(苹果, 1); // emplace_back本身支持传参数包 cout ****************** endl; lt1.push_back({ 苹果,1 }); // listpair隐式类型转换写{ } cout ****************** endl; }总结emplace系列兼容push系列和insert系列部分场景下emplace可以直接构造push和insert是构造移动构造或构造拷贝构造//list接口更新 namespace cxr { templateclass T struct ListNode { // 节点构造完美转发就地构造_data支持emplace template class... Args ListNode(Args... args) : _next(nullptr) , _prev(nullptr) , _data(std::forwardArgs(args)...) {} T _data; ListNodeT* _next; ListNodeT* _prev; }; templateclass T class list { public: using Node ListNodeT; // 容器的emplace_back templateclass... Args void emplace_back(Args... args) { insert(end(), std::forwardArgs(args)...); } // 核心 emplace insert在pos迭代器位置就地构造节点 templateclass... Args void insert(iterator pos, Args... args) { // 直接new节点把参数转发给Node构造函数Node内部再转发给T的构造 Node* newnode new Node(std::forwardArgs(args)...); Node* cur pos._node; Node* prev cur-_prev; prev-_next newnode; newnode-_prev prev; newnode-_next cur; cur-_prev newnode; _size; } // push_back 复用emplace_back void push_back(const T val) { emplace_back(val); } void push_back(T val) { emplace_back(std::move(val)); } iterator end() { return iterator(_head); // _head是哨兵头结点 } private: Node* _head; size_t _size; }; }4. 新的类功能4.1 默认的移动构造和移动赋值1、除了原本的6个默认成员函数构造、析构、拷贝构造、拷贝赋值重载、取地址重载、const取地址重载外C11新增2个默认成员函数移动构造和移动赋值2、若没有自己实现移动构造且没有实现析构、拷贝构造、拷贝赋值重载中任意一个那么编译器就会自动生成一个默认移动构造。3、默认生成的移动构造对于内置类型成员会逐字节拷贝对于自定义类型成员若其实现了移动构造则调用移动构造没有实现就调用拷贝构造4、默认生成的移动赋值的规则同上class Person { public: Person(const char* name , int age 0) :_name(name) , _age(age) { } //Person(const Person p) // :_name(p._name) // ,_age(p._age) //{ } //Person operator(const Person p) //{ // if(this ! p) // { // _name p._name; // _age p._age; // } // return *this; //} //~Person() //{ } private: string _name; int _age; }; int main() { Person s1; Person s2 s1; Person s3 std::move(s1); Person s4; s4 std::move(s2); return 0; }4.2 成员变量声明时给缺省值成员变量声明时给出缺省值用于初始化列表。这里在类和对象部分有讲就不多赘述了。4.3 defult和delete1、在C11中我们可以通过关键字defult来强制生成成员函数的默认版本。class A { public: A() default; // 强制生成默认无参构造 A(const A a) default; // 强制生成默认拷贝构造 A operator (const A a) default; // 强制生成默认拷贝赋值 ~A() default; // 强制生成默认析构 A(A a) default; // 强制生成默认移动构造 };2、在C11中我们利用delete来强制不生成成员函数的默认版本。class A { public: A(const A a) delete; // 强制不生成默认拷贝构造 };4.4 final和override这个在多态一节有讲详情可看C进阶多态-CSDN博客5. lambda表达式5.1 lambda表达式基本语法1、lambda表达式本质是一个匿名函数对象跟普通函数不同的是它可以定义在函数内部。2、就语法而言lambda表达式在使用层没有类型因此我们一般用auto去接收lambda对象。3、基本格式[ capture-list ] ( parameters ) - return type { function body }auto add1 [](int x, int y)-int {return x y; }; // 匿名函数对象 cout add1(1, 2) endl;4、[ capture-list ]捕捉列表出现在lambda函数开始位置编译器通过 [ ] 来判断下面代码是否为lambda函数捕捉列表能捕捉上下文的变量供lambda函数使用。5、( parameters )参数列表若不需要参数则可以连同一起省略。6、- return type返回值类型没有返回值时可以省略一般返回值类型明确的情况下也可以省略由编译器自动推导。7、{ function body }函数体和普通函数一样。8、lambda函数还有以下规则// 1、捕捉为空也不能省略 // 2、参数为空可以省略 // 3、返回值可以省略可以通过返回对象⾃动推导 // 4、函数体不能省略 auto func1 [] { cout hello bit endl; return 0; }; func1(); int a 0, b 1; auto swap1 [](int x, int y) { int tmp x; x y; y tmp; }; swap1(a, b); cout a : b endl;5.2 捕捉列表1、lambda表达式中默认只能用函数体和参数中的变量若想用外层作用域的变量就需要捕捉。2、第一种捕捉方式在捕捉列表中显示的传值捕捉和传引用捕捉捕捉多个变量用逗号分隔。int y0; int main() { // 只能用当前lambda局部域和捕捉的对象和全局对象 int a 0, b 1, c 2, d 3; auto func1 [a, b](int x) // a是传值捕捉b是传引用捕捉 { // 值捕捉的变量不能修改引用捕捉的变量可以修改 //a; b; int ret a b x y; // 全局域的变量不用捕捉可以直接用 return ret; }; cout func1(1) endl; return 0; }3、第二种捕捉方式在列表中隐式捕捉表示隐式值捕捉表示隐式引用捕捉。// 隐式值捕捉 // ⽤了哪些变量就捕捉哪些变量 auto func2 [] { int ret a b c; return ret; }; cout func2() endl; // 隐式引⽤捕捉 // ⽤了哪些变量就捕捉哪些变量 auto func3 [] { a; c; d; }; func3(); cout a b c d endl;4、第三种捕捉方式混合捕捉。使用混合捕捉时第一个元素必须是或第一个是后面的必须是值捕捉第一个是后面的必须是引用捕捉。// 混合捕捉1 auto func4 [, a, b] // a、b值捕捉其余引用捕捉 { //a; //b; c; d; return a b c d; }; func4(); cout a b c d endl; // 混合捕捉2 auto func5 [, a, b] { a; b; /*c; d;*/ return a b c d; }; func5(); cout a b c d endl;5、lambda表达式可以直接使用全局变量和静态变量不用捕捉。若lambda表达式定义在全局域则捕捉列表必须为空。// 局部的静态和全局变量不能捕捉也不需要捕捉 static int m 0; auto func6 [] { int ret x m; return ret; };6、默认情况下lambda捕捉列表是被const修饰的也就是说传值捕捉过来的对象不能修改mutable加在参数列表后面可以取消其常属性但是可以修改的对象只是形参。// 传值捕捉本质是⼀种拷⻉,并且被const修饰了 // mutable相当于去掉const属性可以修改了 // 但是修改了不会影响外⾯被捕捉的值因为是⼀种拷⻉ auto func7 []()mutable { a; b; c; d; return a b c d; }; cout func7() endl; cout a b c d endl;5.3 lambda的应用在学lambda表达式之前我们使用的可调用对象就只有函数指针和仿函数对象。有了lambda表达式在某些场景下就可以不用额外写仿函数直接定义可调用对象struct Goods { string _name; // 名字 double _price; // 价格 int _evaluate; // 评价 // ... Goods(const char* str, double price, int evaluate) :_name(str) , _price(price) , _evaluate(evaluate) { } }; struct ComparePriceLess { bool operator()(const Goods gl, const Goods gr) { return gl._price gr._price; } }; struct ComparePriceGreater { bool operator()(const Goods gl, const Goods gr) { return gl._price gr._price; } }; int main() { vectorGoods v { { 苹果, 2.1, 5 }, { 香蕉, 3, 4 }, { 橙子, 2.2, 3}, { 菠萝, 1.5, 4 } }; // 类似这样的场景我们实现仿函数对象或者函数指针⽀持商品中 // 不同项的⽐较相对还是⽐较⿇烦的那么这⾥lambda就很好⽤了 sort(v.begin(), v.end(), ComparePriceLess()); sort(v.begin(), v.end(), ComparePriceGreater()); sort(v.begin(), v.end(), [](const Goods g1, const Goods g2) { return g1._price g2._price; }); sort(v.begin(), v.end(), [](const Goods g1, const Goods g2) { return g1._evaluate g2._evaluate; }); // 直接写lambda表达式省去了写仿函数对象的麻烦 return 0; }6. 包装器6.1 functiontemplate class T class function; // undefined template class Ret, class... Args class functionRet(Args...);1、std::function 是一个类模板也是一个包装器。std::function 的实例对象可以包装存储其他的可调用对象包括函数指针、仿函数、lambda、bind表达式等存储的可调用对象被称为std::function 的目标。2、若std::function 不含目标则称它为空。调用空std::function 的目标导致抛出 std::bad_function_call 的异常具体链接std::bad_function_call3、这个是官方文件链接std::function4、函数指针、仿函数、 lambda 等可调⽤对象的类型各不相同 std::function 的优势就是统 ⼀类型对他们都可以进⾏包装这样在很多地⽅就方便声明可调⽤对象的类型。// 包装器 #includefunctional int f(int a, int b) { return a b; } struct Functor { public: int operator() (int a, int b) { return a b; } }; class Plus { public: Plus(int n 10) :_n(n) { } static int plusi(int a, int b) { return a b; } double plusd(double a, double b) { return (a b) * _n; } private: int _n; }; int main() { // 包装各种可调⽤对象 functionint(int, int) f1 f; // 包装函数指针 functionint(int, int) f2 Functor(); // 包装仿函数对象 functionint(int, int) f3 [](int a, int b) {return a b; }; // 包装lambda表达式 cout f1(1, 1) endl; cout f2(1, 1) endl; cout f3(1, 1) endl; // 包装静态成员函数 // 成员函数要指定类域并且前⾯加才能获取地址 functionint(int, int) f4 Plus::plusi; cout f4(1, 1) endl; // 包装普通成员函数 // 普通成员函数还有⼀个隐含的this指针参数所以绑定时传对象或者对象的指针过去都可以 functiondouble(Plus*, double, double) f5 Plus::plusd; Plus pd; cout f5(pd, 1.1, 1.1) endl; functiondouble(Plus, double, double) f6 Plus::plusd; // 这里既可以用指针也可以用对象可以匿名对象 cout f6(pd, 1.1, 1.1) endl; cout f6(pd, 1.1, 1.1) endl; functiondouble(Plus, double, double) f7 Plus::plusd; cout f7(move(pd), 1.1, 1.1) endl; cout f7(Plus(), 1.1, 1.1) endl; return 0; }6.2 bind1、bind是一个函数模板它也是一个可调用对象的包装器可以看作函数适配器。2、bind可以用来调整参数个数和参数顺序。// bind绑定 using placeholders::_1; using placeholders::_2; using placeholders::_3; int Sub(int a, int b) { return (a - b) * 10; } int SubX(int a, int b, int c) { return (a - b - c) * 10; } int main() { // bind 本质返回的⼀个仿函数对象 auto sub1 bind(Sub, _1, _2); // 绑定函数指针,_1代表第一个实参_2代表第二个实参 cout sub1(10, 5) endl; auto sub2 bind(Sub, _2, _1); // 绑定函数指针交换参数 cout sub2(10, 5) endl; // 调整参数个数 常⽤ auto sub3 bind(Sub, 100, _1); // 绑死参数a cout sub3(5) endl; auto sub4 bind(Sub, _1, 100); cout sub4(5) endl; // 分别绑死第123个参数 auto sub5 bind(SubX, 100, _1, _2); cout sub5(5, 1) endl; auto sub6 bind(SubX, _1, 100, _2); cout sub6(5, 1) endl; auto sub7 bind(SubX, _1, _2, 100); cout sub7(5, 1) endl; // 成员函数对象进⾏绑死就不需要每次都传递了 //functiondouble(Plus, double, double) f6 Plus::plusd; //Plus pd; //cout f6(move(pd), 1.1, 1.1) endl; //cout f6(Plus(), 1.1, 1.1) endl; // bind⼀般⽤于绑死⼀些固定参数 functiondouble(double, double) f7 bind(Plus::plusd, Plus(), _1, _2); cout f7(1.1, 1.1) endl; // 计算复利的lambda // 前一年的本金利息下一年的本金 // 复利公式本金*1利率^年数-本金 auto func1 [](double rate, double money, int year)-double { double ret money; for (int i 0; i year; i) { ret ret * rate; } return ret - money; }; cout func1(0.05, 100000, 3) endl; // 绑死⼀些参数实现出⽀持不同年华利率不同⾦额和不同年份计算出复利的结算利息 functiondouble(double) func3_1_5 bind(func1, 0.015, _1, 3); // 3年期1.5%利率_1表示传入的本金 functiondouble(double) func5_1_5 bind(func1, 0.015, _1, 5); functiondouble(double) func10_2_5 bind(func1, 0.025, _1, 10); cout func3_1_5(1000000) endl; cout func5_1_5(1000000) endl; cout func10_2_5(1000000) endl; return 0; }本期的分享就到这里如果觉得博主的文章比较对胃口的话可以点一个小小的关注~您的三连是我持续更新的动力~

相关新闻

AI编程工具实战:从效率提升到产品开发加速的工程闭环

AI编程工具实战:从效率提升到产品开发加速的工程闭环

最近在技术社区看到不少关于“AI 会不会取代程序员”的讨论,也看到 Meta CTO 关于“AI 省下的时间应投入开发产品”的观点,这让我思考良多。作为一名长期在一线写代码、做项目的开发者,我深切感受到,AI 工具(如 GitHub…

2026/10/11 6:34:32 阅读更多 →
3个简单步骤:用开源AI工具Upscayl让模糊照片变高清

3个简单步骤:用开源AI工具Upscayl让模糊照片变高清

3个简单步骤:用开源AI工具Upscayl让模糊照片变高清 【免费下载链接】upscayl 🆙 Upscayl - #1 Free and Open Source AI Image Upscaler for Linux, MacOS and Windows. 项目地址: https://gitcode.com/GitHub_Trending/up/upscayl 你是否曾因老照…

2026/10/8 19:54:03 阅读更多 →
从Function Calling到MCP:AI工具集成的协议化演进与实战

从Function Calling到MCP:AI工具集成的协议化演进与实战

1. 项目概述:从“黑盒”调用到“协议”对话如果你在过去一年里折腾过AI应用开发,尤其是基于大语言模型(LLM)构建能“动手做事”的智能体(Agent),那么“Function Calling”这个词你一定不陌生。它…

2026/10/7 5:34:10 阅读更多 →

最新新闻

MySQL慢查询定位与索引设计:EXPLAIN与B+树实战全解析

MySQL慢查询定位与索引设计:EXPLAIN与B+树实战全解析

接手线上业务系统这几年,最让我头疼的问题之一就是MySQL慢查询。明明功能开发完了、测试也过了,一到流量高峰期,几个核心接口突然就卡了几秒,数据库CPU飙高,紧接着就是连接数打满、应用报错。排查下来,十有…

2026/10/13 11:00:03 阅读更多 →
ASIO2WASAPI:让普通声卡也能跑低延迟ASIO的桥接实践

ASIO2WASAPI:让普通声卡也能跑低延迟ASIO的桥接实践

简介:ASIO2WASAPI 是面向 Windows Vista 及以上系统的开源音频驱动方案,为音乐制作人与音频工程师提供硬件无关的 ASIO 支持。它借助中间层将 ASIO 协议和 Windows 原生 WASAPI 结合,用独占模式逼近硬件极限延迟,解决无专用音频接…

2026/10/13 11:00:03 阅读更多 →
JumpServer统一纳管PostgreSQL:从资产配置到安全审计的完整实践

JumpServer统一纳管PostgreSQL:从资产配置到安全审计的完整实践

搞了这么多年运维,数据库资产一直是权限管理里最让人头疼的一环。尤其PostgreSQL这种逻辑库多、角色权限细的系统,直接让人连生产库,账号密码满天飞不说,出事了你连谁干的都查不到。前阵子刚把一套PostgreSQL完整接进了JumpServer…

2026/10/13 11:00:03 阅读更多 →
MySQL Workbench 从下载到实战:安装避坑、连接配置与日常管理技巧

MySQL Workbench 从下载到实战:安装避坑、连接配置与日常管理技巧

最早学数据库那会儿,我一直在黑窗口里敲命令。建表、导数据、改权限全靠手打,一条语句写错就得整条回滚,效率低不说,眼睛也是真遭罪。后来换了 MySQL Workbench,整个体验完全不一样:不用背那么多命令&#…

2026/10/13 11:00:03 阅读更多 →
快速搭建规范开源项目:从零构建可协作可维护的GitHub仓库

快速搭建规范开源项目:从零构建可协作可维护的GitHub仓库

1. 为什么“快速搭建规范开源项目”这件事,比你想象中更值得花时间 “快速在GitHub搭建一个规范的开源项目(一)”——这个标题里藏着三个被新手普遍低估的关键词: 快速 、 规范 、 (一) 。不是“建个…

2026/10/13 11:00:03 阅读更多 →
用帕累托图做线上问题优先级排序:从频次统计到加权决策

用帕累托图做线上问题优先级排序:从频次统计到加权决策

作为负责线上稳定性的工程师,我每天到工位后的第一件事,不是看代码,而是先扫一眼昨夜的问题清单。以前团队排故障优先级基本靠嗓门,谁在群里吼得凶就修谁的;直到我们用帕累托图把问题频次和影响摊开做排序,…

2026/10/13 10:58:59 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →