【问题标题】:nested iterator loop, why are iterators equal? - c++嵌套迭代器循环,为什么迭代器相等? - C++
【发布时间】:2013-04-19 08:56:18
【问题描述】:

我想在对象数组上构造嵌套循环,具有相当复杂的数据结构。因为我使用数组,所以我想利用它们的迭代器。在我得到意想不到的结果后,我将问题归结为以下代码 sn-p,它表明我的迭代器在我期望它们不同时是相等的:

vector<int> intVecA;
vector<int> intVecB;

intVecA.push_back(1);
intVecA.push_back(2);

intVecB.push_back(5);
intVecB.push_back(4);

Foo fooOne(intVecA);
Foo fooTwo(intVecB);

vector<int>::const_iterator itA = fooOne.getMyIntVec().begin();
vector<int>::const_iterator itB = fooTwo.getMyIntVec().begin();
cout << "The beginnings of the vectors are different: "
     << (fooOne.getMyIntVec().begin() == fooTwo.getMyIntVec().begin()) << endl;
cout << (*(fooOne.getMyIntVec().begin()) == *(fooTwo.getMyIntVec().begin())) << endl;
cout << (&(*(fooOne.getMyIntVec().begin())) == &(*(fooTwo.getMyIntVec().begin()))) << endl;
cout << "But the iterators are equal: "
     << (itA==itB) << endl;

这会产生:

The beginnings of the vectors are different: 0
0
0
But the iterators are equal: 1

这种行为对我来说没有意义,我很乐意听到解释。

Foo 是一个简单的对象,其中包含一个向量和 getter 函数:

class Foo {
    public:
    Foo(std::vector<int> myIntVec);

    std::vector<int> getMyIntVec() const {
    return _myIntVec;
    }

    private:
    std::vector<int> _myIntVec;
};

Foo::Foo(std::vector<int> myIntVec) {
    _myIntVec = myIntVec;
}

当第一次复制向量时,问题就消失了。为什么?

vector<int> intVecReceiveA = fooOne.getMyIntVec();
vector<int> intVecReceiveB = fooTwo.getMyIntVec();

vector<int>::const_iterator newItA = intVecReceiveA.begin();
vector<int>::const_iterator newItB = intVecReceiveB.begin();

cout << "The beginnings of the vectors are different: "
     << (intVecReceiveA.begin() == intVecReceiveB.begin()) << endl;
cout << "And now also the iterators are different: "
     << (newItA==newItB) << endl;

产生:

The beginnings of the vectors are different: 0
And now also the iterators are different: 0

补充说明: 我需要函数中的这些嵌套循环,这些循环在计算时间方面需要非常高效,因此我不想做不必要的操作。由于我是 C++ 新手,我不知道复制向量是否真的需要额外的时间,或者它们是否会在内部被复制。我也感谢任何其他建议。

【问题讨论】:

  • “我不知道复制向量是否真的需要额外的时间”——是的,它会。

标签: c++ arrays iterator nested-loops


【解决方案1】:

问题是您在 Foo 中的访问器:

std::vector<int> getMyIntVec() const {
return _myIntVec;
}

我不返回 _myIntVec,它返回 myIntVec 的副本。 相反,它应该看起来像:

const std::vector<int>& getMyIntVec() const {
return _myIntVec;
}

否则,当您创建迭代器时,它们是从直接丢弃的副本中创建的,因此您的 C++ 编译器会重用该地址。这就是为什么你会得到“相等”的迭代器,至少我是这么认为的。

【讨论】:

  • 这确实解决了问题。感谢您快速、准确和解释性的回答。现在这对我来说是有道理的,虽然我现在还不清楚为什么这些副本会被直接扔掉。
【解决方案2】:

你意识到你比较事物的方式是错误的吗?如果你比较a == b,即使你写了

cout << "a is different from b: " << (a==b) << endl;

输出将告诉两个元素是否相同而不是不同。要检查两件事是否不同,请使用 != 而不是 ==。

【讨论】:

  • 抱歉,我显然不清楚输出字符串和比较的构造。我的想法是识别相等与真,差异与假,而不是构建陈述为真。我知道我比较了什么以及如何比较。
【解决方案3】:

这样做的原因是比较两个引用不同容器中元素的迭代器是未定义的行为。所以,不能保证你会得到什么。这是因为getMyIntVec 返回了_MyIntVec 的副本,并且您将这些副本分配给vector&lt;int&gt; 的新实例,因此它们确实是_MyIntVec 成员的两个不同副本的迭代器。

按照标准:

§ 24.2.1

一个迭代器 j 被称为从一个迭代器 i 可达的当且仅当存在一个有限的 使 i == j 的表达式 ++i。如果 j 可以从 i 到达,则它们指的是同一序列的元素。

标准稍晚一点:

§ 24.2.5

前向迭代器的 == 域是相同底层序列上的迭代器的域。

this question已经回答了这个问题

【讨论】:

    【解决方案4】:

    你这里有一个严重的逻辑问题:

    cout << "The beginnings of the vectors are different: "
     << (fooOne.getMyIntVec().begin() == fooTwo.getMyIntVec().begin()) << endl;
    

    如果它们相等,它将输出 1 而不是您通常期望的 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多