【问题标题】:The relationship between iterators and containers in STLSTL中迭代器和容器的关系
【发布时间】:2011-01-15 02:22:50
【问题描述】:

美好的一天,

假设我正在用 C++ 编写一个类似 Python 的范围。它提供了随机访问容器的所有特性(当然是不可变的)。关于以下情况,我想到了一个问题:

我有两个不同的迭代器,它们指向范围容器的 不同 实例。问题是这两个范围相等。即它们代表相同的范围。您是否允许以下​​情况:

fact: range1 == range2 e.g.
---------------------------
range range1(10, 20, 1), range2((10, 20, 1);
range::iterator i = range1.begin(), j = range2.begin();
assert(i == j); // would you allow this?

对不起,如果我在 STL 中遗漏了一个简单的设计规则 :)

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    默认情况下,在 STL 中,来自两个不同容器的两个迭代器是不可比较的。这意味着,行为是未指定的。所以你想做什么就做什么,没有人应该尝试。

    编辑

    仔细查看标准后,第 24.1 节第 6 段指出:

    一个迭代器 j 被称为reachable from 一个迭代器 i 当且仅当有 一个有限的应用序列 使 i == j 的表达式 ++i。 如果 j 可以从 i 到达,他们指的是 到同一个容器。

    这意味着如果您允许 i == jij 在两个不同的容器中,您真的认为这两个容器是相同的。因为它们是不可变的,所以这很好。只是语义问题。

    【讨论】:

    • 谢谢。这是我第一次知道这个:) 你知道我在哪里可以找到标准吗?
    • 我要补充一点,如果您使用的是字符串,并且如果实现对所有字符串执行了实习操作,那么比较两个 == 字符串可能会导致相同的行为。这不是必需的,但它可能会发生。如果真的发生了,我不会担心,但我也不会要求它发生。
    • 当您尝试比较指向不同容器的迭代器时,VC 至少会抱怨。你知道标准是否规定比较它们是非法的吗?还是 VC 的帮助太大了? 24.1 的第 7 段看起来最接近现在的说法,但它实际上是在描述“范围”和“算法”。问题是,比较 'i == j' 是否有效,即使它们不指向同一个容器?
    【解决方案2】:

    您可能想查看boost::counting_iterator。结合boost::iterator_range,你会得到类似于你的范围类的东西(除了它只允许步长为 1):

    auto rng = boost::make_iterator_range(boost::make_counting_iterator(0),
                                          boost::make_counting_iterator(10));
    for(auto it = rng.begin(), e = rng.end(); it != e; ++it)
        std::cout << it << " "; // Prints 0,1,2,3,...,9
    

    对于这个类,两个迭代器被认为是相等的,只要它们包含相同的数字。但诚然,情况与您的情况不同,因为这里每个迭代器都不知道它属于哪个范围。

    【讨论】:

      【解决方案3】:

      在 STL 中,比较规则是由容器的元素而不是容器本身驱动的,所以在我看来,您不应该在 == 运算符重载中执行自己的取消引用。

      【讨论】:

        猜你喜欢
        • 2013-04-16
        • 2011-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-05
        • 1970-01-01
        • 2021-02-14
        相关资源
        最近更新 更多