您的位置:首页 > 文旅 > 美景 > saas系统是什么意思啊_公司网站设计素材_深圳快速seo排名优化_文山seo公司

saas系统是什么意思啊_公司网站设计素材_深圳快速seo排名优化_文山seo公司

2025/4/29 20:49:01 来源:https://blog.csdn.net/m0_49013185/article/details/147080964  浏览:    关键词:saas系统是什么意思啊_公司网站设计素材_深圳快速seo排名优化_文山seo公司
saas系统是什么意思啊_公司网站设计素材_深圳快速seo排名优化_文山seo公司

Day12-2 访问容器中的元素

下面种遍历方式都能正确访问 std::vector<std::unique_ptr<int>> 中的元素,但它们各有特点和潜在问题点,我们逐一分析:


✅ 第一种:范围 for + 自动类型推导

for (auto& value : vec)
{cout << *value << endl;
}
✔ 优点:
  • 简洁且安全。
  • valuestd::unique_ptr<int>&,不会发生值拷贝或所有权转移。
  • 推荐做只读或修改指针指向的内容时使用。
⚠ 缺点:
  • 仅当你熟悉 auto 推导规则时清晰易懂;否则不显式写类型可能阅读性略差。

✅ 第二种:范围 for + 显式类型

for (std::unique_ptr<int>& value : vec)
{cout << *value << endl;
}
✔ 优点:
  • 显式指出变量类型,阅读性更强,对学习者更友好。
  • 同样是引用,不会转移所有权。
⚠ 缺点:
  • 相较于 auto& 略显啰嗦,但功能等价。

✅ 第三种:使用下标访问

for (size_t i = 0; i < vec.size() ; i++)
{cout << *vec[i];cout << vec.at(i);
}
✔ 优点:
  • 可以使用下标 i,方便访问前后元素(如 i+1,i-1)。
  • 支持 vec.at(i),带越界检查。
⚠ 缺点:
  • 每次访问都需调用 operator[]at(),可能比迭代器略慢(虽然差别极小)。
  • vec.at(i) 会抛异常,vec[i] 不会,容易写出 越界访问 错误。
  • 不如基于范围的 for 简洁。

总结建议:

遍历方式安全性可读性性能推荐用途
for (auto& value : vec)中-高推荐日常遍历
for (std::unique_ptr<int>& value : vec)学习阶段推荐
for (size_t i = 0; i < vec.size(); ++i)需访问索引或相邻元素时使用

如果你不打算修改指针本身,也可以加上 const 修饰,提升表达意图的清晰度:

for (const std::unique_ptr<int>& value : vec)
{cout << *value << endl;
}

或者:

for (const auto& value : vec)
{cout << *value << endl;
}

你已经用了三种遍历方式来访问 std::vector<std::unique_ptr<int>> 中的元素:

  1. 基于范围的 for 循环(引用)
  2. 显式使用引用类型的基于范围的 for 循环
  3. 使用索引 vec[i]vec.at(i)

除了这些,还有以下几种方式可以遍历 vec


✅ 第四种:使用迭代器(推荐理解底层原理)

for (auto it = vec.begin(); it != vec.end(); ++it) {cout << *(*it) << endl; // *it 是 unique_ptr,*(*it) 是 int
}

✅ 第五种:使用 std::for_each 算法

std::for_each(vec.begin(), vec.end(), [](const std::unique_ptr<int>& ptr) {cout << *ptr << endl;
});

✅ 第六种:使用 std::ranges::for_each(C++20)

#include <ranges>std::ranges::for_each(vec, [](const std::unique_ptr<int>& ptr) {cout << *ptr << endl;
});

✅ 第七种:使用 transform 做一些额外操作(如果你需要构造另一个容器)

std::vector<int> values;
std::transform(vec.begin(), vec.end(), std::back_inserter(values),[](const std::unique_ptr<int>& ptr) {return *ptr;});for (int val : values) {cout << val << endl;
}

小提示

如果你只是访问 unique_ptr 中的值,用 const std::unique_ptr<int>& 是最好的方式,因为:

  • 不会移动所有权
  • 不会复制指针
  • 安全且高效

好问题!你问的是:

为什么迭代器遍历 vector<unique_ptr<int>> 时需要两次解引用?

来看一下这段代码:

for (auto it = vec.begin(); it != vec.end(); ++it) {cout << *(*it) << endl; // 两次解引用
}

🌟 理解第一次解引用 \*it
  • it 是一个 迭代器,类型为:std::vector<std::unique_ptr<int>>::iterator
  • 所以 *it 得到的是 unique_ptr<int>&,即指向容器中某个 unique_ptr<int> 的引用。
🧠 理解第二次解引用 \*(\*it)
  • *itunique_ptr<int>&,所以 *(*it) 就是访问 unique_ptr 所管理的对象,也就是 int
  • 所以最终你得到的是 int 的值。
    在这里插入图片描述

🧩 类比一下(更容易理解):

假设你有一个 vector<string*>

std::vector<std::string*> vec;
vec.push_back(new std::string("Hello"));for (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << **it << std::endl; // 同样是两次解引用
}

为什么也是 **it?因为:

  • *itstring*(一个裸指针)
  • **itstring 的内容

✅ 回到 unique_ptr<int> 的情况:
std::vector<std::unique_ptr<int>> vec;
  • vec[i] 是一个 unique_ptr<int>
  • 所以 *vec[i]int
  • 迭代器 it*itunique_ptr<int>&,再 *(*it) 就是 int

📝 总结口诀:

容器里装指针(包括智能指针),访问内容就要两次 \*

第一次 * 拿到指针,第二次 * 拿到内容。


如果你想更简单一些,不用管两次 *,可以用:

for (const auto& ptr : vec) {std::cout << *ptr << std::endl;
}

它内部其实也是做了两次 *,只是你没写出来而已 😄

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com