【问题标题】:C++: using const with STL iteratorsC++:将 const 与 STL 迭代器一起使用
【发布时间】:2010-07-25 18:02:54
【问题描述】:

来自Effective C++,第 3 项

/* case1 */ const std::vector<int>::iterator i  // i  acts like a T* const
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T*

为了记住const是如何应用的,我曾经记住this article的以下内容

基本上'const'适用于任何东西 就在它的左边(除了 如果那里什么都没有 它适用于它的任何东西 立即正确)。

当我第一次阅读本书中的第 3 项时,我预计 case1 和 case2 会反过来。

我应该将这种情况视为例外吗?还是我缺少一些更深层次的理解?

【问题讨论】:

    标签: c++ templates stl constants effective-c++


    【解决方案1】:

    该规则如宣传的那样起作用。

    const std::vector<int>::iterator i
    

    右边的项目是iterator:迭代器是不可变的。您不能将迭代器分配为指向向量中的不同项目,也不能递增它,它始终指向它被初始化的项目。不过,您可以更改所指向的项目。

    这很少是期望的行为,这就是const_iterator typedef 存在的原因。

    std::vector<int>::const_iterator ci
    

    迭代器可以移动,但指向的项目不能修改。这几乎总是你想要的——你想迭代一个向量但不能修改它的内容。

    这里没有const 关键字,因此您不能使用该规则来找出它。对于这一点,您只需要了解 const_iterator 记录的用途即可。

    【讨论】:

    • 我发现第一个案例有用的一个地方是保存搜索的输出,比如来自std::find_ifconst std::vector&lt;int&gt;::iterator i = std::find_if(...); 表示我想记住搜索的结果,并且我不想无意中更改该结果。
    【解决方案2】:

    你可以把它想象成迭代器是typedefed,就像这样:

    typedef T* iterator;
    typedef const T* const_iterator;
    

    当您将const 添加到其中任何一个时,它会在顶层应用,即应用于指针本身,而不是指向的对象,因此以下等价性成立:

    const iterator it; // is the same as:
    T* const it;
    
    const const_iterator it; // is the same as:
    const T* const it;
    

    他们也不例外;这就是所有typedefs 的工作方式。

    【讨论】:

      【解决方案3】:

      引用的规则绝对适用于const 关键字。但是,在处理迭代器时,const_iterator 类只是这样命名(它同样可以是 readonly_iterator),因此关于 const 关键字的规则不适用。

      但是,您可以像这样声明案例 1:

      std::vector<int>::iterator const i
      

      就像您可以指定 const int xint const x 一样。

      迭代器指向的类型也是在其容器的模板参数中指定的,因此排序与声明普通变量不同。

      我看不出这里有什么特别的经验法则可以遵循 - 你帖子中的 cmets 是正确的想法,你只需要学会将const_iterator 视为const T* 等等。

      【讨论】:

        【解决方案4】:

        我认为 const_iterator 让您感到困惑。这是一个使用更简单的 typedef 的示例。

        typedef int* Type;
        typedef const int* ConstType;
        
        int main() {
          const Type a; // int * const
          ConstType b; // const int *
        }
        

        【讨论】:

          【解决方案5】:

          案例 1 中的 const 适用于迭代器,因此它使迭代器本身为 const。它对迭代器“指向”的项目没有任何影响。 (这就像在T* const 中,指针是const,而不是指向的T

          在情况 2 中,const 只是名称 const_iterator 的一部分,因此无法真正推断出那里的 const 是什么。该类可能只是有一个坏名字,而且根本就没有 const 。然而,在这种情况下,const_iterator 不允许修改它的目标元素,因为它的定义与标准库中的定义类似。

          【讨论】:

            猜你喜欢
            • 2013-05-30
            • 2012-01-28
            • 1970-01-01
            • 2015-02-04
            • 1970-01-01
            • 1970-01-01
            • 2011-03-22
            • 2010-10-05
            • 2012-03-16
            相关资源
            最近更新 更多