Item13:优先选用const_iterator,而非iterator
STL 的const_iterator等价于 “指向常量的指针(pointer-to-const)”,指向的值不可修改,符合 “能加const就加” 的通用编程准则 —— 只要无需修改迭代器指向的值,就应优先使用const_iterator;但该迭代器的实用性随 C++ 版本迭代大幅提升,C++11 是关键转折点,同时通用代码中需优先使用非成员函数版本的begin/end/cbegin等。
各 C++ 版本对 const_iterator 的支持差异
1. C++98:支持残缺,实用性差
const_iterator理论上符合规范,但实际使用存在两大痛点:
创建麻烦:非
const容器无法直接获取const_iterator,需强制类型转换(或绑定到const引用)才能得到;使用受限:
insert/erase等容器操作仅接受iterator,且const_iterator无法可移植转换为iterator(即使reinterpret_cast也不行);最终导致开发者被迫放弃使用,违背 “能
const则const” 的准则。
1 | typedef std::vector<int>::iterator IterT; |
C++11:支持完善,易用性大幅提升
解决了 C++98 的核心痛点,让const_iterator真正实用:
容器新增
cbegin/cend成员函数,非const容器也能直接获取const_iterator;insert/erase等操作支持接收const_iterator,无需转换即可使用;示例:无需修改迭代器指向值的查找 + 插入场景,可直接用
cbegin/cend获取const_iterator,代码简洁且符合规范。
1 | std::vector<int> values; |
C++11 的小缺陷与 C++14 的补全
- C++11 仅新增非成员函数
begin/end,缺失cbegin/cend/rbegin/rend等; - C++14 补全了这些非成员函数,满足 “最大程度通用的库代码” 需求(适配原生数组、仅提供自由函数接口的第三方库等)。
通用代码的适配方案(C++11 兼容)
若 C++11 环境下 STL 未提供非成员cbegin等函数,可自行实现(兼容普通容器和原生数组):
- 核心逻辑:通过
const引用接收容器 / 数组,调用 C++11 提供的非成员begin—— 对const容器 / 数组,begin会自动返回const_iterator(数组场景下等价于指向const的指针); - 无需依赖容器的
cbegin成员函数,适配性更强。
总结
- 优先选用
const_iterator,而非iterator。 - 在最通用的代码中,优先选用非成员函数版本的
begin、end和rbegin等,而非其成员函数版本。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 肖恩的博客!
评论
