尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

C++ 范围 for 的复制陷阱:auto、auto、const auto 怎么选

C++ 范围 for 的复制陷阱:auto、auto、const auto 怎么选 C 范围 for 的复制陷阱auto、auto、const auto 怎么选范围 for 很好读但下面三个写法含义不同auto 会得到一个元素副本auto 引用原元素const auto 只读引用。对小整数这点差别可能不明显对大对象或不可复制对象它既影响性能也可能决定代码能否编译。1. 只读访问先考虑 const auto#includestring#includevectorintmain(){std::vectorstd::stringnames{Alice,Bob};for(constautoname:names){// 只读使用 name不逐个复制字符串}}若写 for (auto name : names)每轮都会构造一个新的 std::string。对 std::unique_ptr 等不可复制类型auto 甚至会报错。只有明确需要独立副本或元素是 int 这样的轻量值时才优先按值拿。2. 修改原元素使用 auto#includevectorintmain(){std::vectorintvalues{1,2,3};for(autovalue:values){value*2;}// values 现在是 {2, 4, 6}}如果误写成 auto value循环体改的是副本原容器不会变化。对关联容器元素有自己的常量约束遍历 map 时即使用 auto键通常仍不可改映射值则可以修改。3. 特殊情况代理对象与 autostd::vector 为节省空间其元素访问可能返回代理对象而不是真正的 bool。对这类容器auto 更通用#includevectorintmain(){std::vectorboolflags{false,true};for(autoflag:flags){flagtrue;}}这里的 auto 会按当前元素表达式完成推导既能处理普通引用也能处理代理对象。它不是“总会移动元素”的意思。4. 遍历时不要随意增删 vector范围 for 底层依赖迭代器。遍历中对 vector 做 push_back、erase 等操作可能使迭代器失效随后继续循环就会出现未定义行为。需要删除时优先用 std::erase_ifC20或 erase-remove需要边遍历边改结构时改用显式迭代器并按操作返回值更新它。写法适合的意图auto x需要一份独立的值const auto x只读、避免复制auto x修改原元素auto x泛型代码或代理元素写范围 for 前先问自己“我要读、改还是复制”把这一点想清楚很多隐蔽问题就没了。
返回列表