const-container-s-iterator-is-const-iterator

本文详细解析了C++中容器如vector的迭代器特性,特别是对于const容器如何使用const_iterator进行元素遍历。探讨了非成员版begin()和end()函数的用法,并提供了cbegin()的一个实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值