嵌套迭代器循环,为什么迭代器相等? - c ++

时间:2013-04-19 08:56:18

标签: c++ arrays iterator nested-loops

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

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是一个包含vector和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 ++的新手,我不知道复制向量是否实际需要额外的时间,或者是否会在内部复制它们。我也很感谢任何其他建议。

4 个答案:

答案 0 :(得分:2)

问题是你在Foo中的访问者:

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

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

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

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

这样做的原因是比较两个引用不同容器中元素的迭代器是未定义的行为。所以,不能保证你会得到什么。这是因为getMyIntVec返回_MyIntVec的副本并将这些副本分配给vector<int>的新实例,因此这些实际上是_MyIntVec的两个不同副本的迭代器会员。

根据标准:

§24.2.1

  

迭代器j被称为可从迭代器i到达,当且仅当存在有限的应用程序序列时   使得i == j的表达式++ i。如果j可以从i到达,则它们引用相同序列的元素。

稍后在标准中:

§24.2.5

  

前向迭代器的==域是同一基础序列上的迭代器的域。

这已在this question

中得到解答

答案 3 :(得分:0)

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

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

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