title: const container’s iterator is const_iterator
date: 2022-09-17 13:33:39
tags:
- ‘Modern C++’
- C++
就拿vector举例子
我们转到其代码
template<typename _Container>
inline _GLIBCXX17_CONSTEXPR auto
begin(_Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to the first element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
inline _GLIBCXX17_CONSTEXPR auto
begin(const _Container& __cont) -> decltype(__cont.begin())
{ return __cont.begin(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the container.
* @param __cont Container.
*/
template<typename _Container>
inline _GLIBCXX17_CONSTEXPR auto
end(_Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to one past the last element of
* the const container.
* @param __cont Container.
*/
template<typename _Container>
inline _GLIBCXX17_CONSTEXPR auto
end(const _Container& __cont) -> decltype(__cont.end())
{ return __cont.end(); }
/**
* @brief Return an iterator pointing to the first element of the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX14_CONSTEXPR _Tp*
begin(_Tp (&__arr)[_Nm]) noexcept
{ return __arr; }
/**
* @brief Return an iterator pointing to one past the last element
* of the array.
* @param __arr Array.
*/
template<typename _Tp, size_t _Nm>
inline _GLIBCXX14_CONSTEXPR _Tp*
end(_Tp (&__arr)[_Nm]) noexcept
{ return __arr + _Nm; }
可以看见对于const的重载版本,返回的为const_iterator.
思考
在Modern Effective C++中说到,在通用的代码中,优先选用非成员版的begin()/end(),也正是因为如此。
书中给出了cbegin()的一种实现方式。
template <typename C>
auto cbegin(const C & c)-> decltype(c.begin()) {
return c.begin();
}
因为对于具有const性质的容器(在标准库中的是这样,如果是其他库提供的容器,可能不会提供这样的行为),返回的迭代器是const_iterator,所以,这样做是正确的。
对于数组来说,也是一样的。begin对于数组有特例化。 上面的代码已经看到了。
当数组具有const性质的时候,例如const int nums[10], _Tp会被推导为const int, 返回类型就是const int *, 就是数组的const_iterator