我完全同意你的观点。 我认为答案很简单: 在需要使用const值时请使用const_iterator,反之亦然。 对我而言,那些反对const_iterator的人一定是反对const的。
void some_operation(std::vector<int>& vec, std::vector::const_iterator pos);
some_operation
可以自由修改底层集合,但不允许修改pos
所引用的内容。这没有多少意义。如果您真的想要这样做,那么pos
应该是一个偏移量而不是迭代器。iterator
和const_iterator
之间的区别在于是否可以通过迭代器修改集合中的值。没有对集合的引用,这种分离非常清晰。我通常更喜欢使用const,但最近在处理const_iterators时遇到了一个难题,这让我对“尽可能使用const”的理念感到困惑:
MyList::const_iterator find( const MyList & list, int identifier )
{
// do some stuff to find identifier
return retConstItor;
}
既然传递const列表引用需要我只使用const迭代器,现在如果我使用find,我除了查看结果之外什么都不能做,即使我只想表达find不会改变被传入的列表。
我想知道,Scott Mayers的建议是否与这样的问题有关,即无法摆脱const性质。据我所知,您不能(可靠地)通过简单的转换取消const_iterators的const属性,因为涉及到一些内部细节。这也可能是问题所在。
这可能与此相关:如何去除const_iterator的const属性?
const_iterator
,另一个接受非const引用并返回iterator
。任何返回非const指针、引用或迭代器的函数都应该接受非const参数,即使它不改变对象本身。 - Mark Ransominsert
/erase
等现在都接受const_iterator
。 - Zizheng Tai我认为我们需要考虑Meyers的陈述是关于C++98的。虽然现在很难确定,但如果我没记错:
例如:
std::vector<int> container;
would have required
static_cast<std::vector<int>::const_iterator>(container.begin())
std::vector<int>::const_iterator i = std::find(static_cast<std::vector<int>::const_iterator>(container.begin()), static_cast<std::vector<int>::const_iterator>(container.end()),42);
std::vector<int> container;
auto i = std::find(container.cbegin(), container.cend(), 42);
container.insert(i, 43);
因为第一个优选迭代器而不是const_iterators只是历史实现缺陷的产物。
今天,真的真的应该优先选择const_iterators而不是迭代器
我认为Meyer的这个陈述并不需要特别关注。当您需要进行非修改操作时,最好使用const_iterator
。否则,请使用普通的iterator
。但是,请注意一件重要的事情:永远不要混合使用迭代器,即const
和non-const
迭代器。只要您意识到后者,就应该没问题。
iterator
的原因是,像std::vector::insert
/std::vector::erase
这样的方法都需要使用iterator
,所以使用其他任何东西(例如const_iterator
)都没有好处。但自从C++11以来,这些方法都采用了const_iterator
(std::vector::insert
,std::vector::erase
),因此现在没有理由优先选择iterator
而不是const_iterator
。尽可能使用const
版本。 - Zizheng Tai