【问题标题】:Comparing default-constructed iterators with operator==将默认构造的迭代器与 operator== 进行比较
【发布时间】:2010-11-14 11:26:19
【问题描述】:

C++ 标准是否说我应该能够比较两个默认构造的 STL 迭代器是否相等?默认构造的迭代器是等价可比的吗?

我想要以下内容,例如使用 std::list:

void foo(const std::list<int>::iterator iter) {
    if (iter == std::list<int>::iterator()) {
        // Something
    }
}

std::list<int>::iterator i;
foo(i);

我在这里想要的是迭代器的 NULL 值,但我不确定它是否合法。在 Visual Studio 2008 中包含的 STL 实现中,它们在 std::list 的 operator==() 中包含了排除这种用法的断言。 (他们检查每个迭代器是否由同一个容器“拥有”,并且默认构造的迭代器没有容器。)这暗示它不合法,或者他们可能过于热心。

【问题讨论】:

  • boost::optional&lt;std::list::iterator&gt; 浮现在脑海中。

标签: c++ visual-studio-2008 stl iterator


【解决方案1】:

好的,我会采取行动。 C++ 标准,第 24.1/5 节:

迭代器也可以有单数 不相关的值 任何容器。 [示例:之后 未初始化的声明 指针 x(与 int* x; 一样),x 必须 总是假设有一个单数 指针的值。 ] 大多数的结果 单数表达式未定义 价值观;唯一的例外是 将非奇异值分配给 包含单数的迭代器 价值。

所以,不,它们无法比较。

【讨论】:

  • `std::istream_iterator 怎么样。这正是您比较测试结束的方式。
【解决方案2】:

这将在 C++14 中改变。 [forward.iterators] N3936 的 24.2.5p2 说

然而,值初始化的迭代器可以被比较并且应该被比较 等于其他相同类型的值初始化迭代器。

【讨论】:

  • 我现在在工作中实现某些东西时遇到了这个问题:(我希望我有 c++2014 但只有 Visual Studio 2012:D
  • 即使在 C++14 中这仍然不是一个好主意,因为非奇异迭代器无法与值初始化的迭代器进行比较。
  • 不,这并没有真正改变任何事情。仅仅因为您可以比较两个值初始化的迭代器并不意味着您可以将一个值初始化的迭代器与其他一些迭代器进行比较。你不能。在后一种情况下,即使在 C++14 之后,行为仍然未定义。
【解决方案3】:

我认为您应该将 范围 传递给函数。

void fun(std::list<int>::iterator beg, std::list<int>::iterator end)
{
    while(beg != end)
    {
        // do what you want here.
        beg++;
    }
}

【讨论】:

  • 可能是真的,但没有回答问题。
  • 我明白你在说什么,但语义确实需要单个项目——很像 std::list::erase()。我可能在滥用迭代器的概念;这就是我感兴趣的发现。
  • AraK,你可以通过什么方式传入一个“null”迭代器?
  • @Andy,我不明白你的问题。
  • 重点是 range-function 有同样的问题 - 并给出了允许在 C++14 中进行比较的充分理由。您可以在调用例程中默认构造“beg”和“end”(然后可能将它们设置为实际范围)并调用“fun”。这需要在两个默认构造的迭代器“beg”和“end”之间进行相同的测试。 (你不能假设调用例程总是可以访问适当的容器。)
【解决方案4】:

规范说默认构造函数的后置条件是迭代器是singular。相等的比较是未定义的,因此在某些实现中可能会有所不同。

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 2020-12-14
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多