嵌套迭代器循环,为什么迭代器是相等的?——c++
nested iterator loop, why are iterators equal? - c++
我想在对象数组上构造嵌套循环,具有相当复杂的数据结构。因为我使用数组,所以我想利用它们的迭代器。在得到意想不到的结果后,我将问题归结为以下代码片段,它显示了当我期望迭代器不同时它们是相等的:
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++的新手,我不知道复制向量是否会实际花费额外的时间,或者它们是否会在内部复制。
问题是您在Foo中的访问器:
std::vector<int> getMyIntVec() const {
return _myIntVec;
}
I不返回_myIntVec,它返回myIntVec的副本。相反,它应该看起来像:
const std::vector<int>& getMyIntVec() const {
return _myIntVec;
}
否则,当你创建迭代器时,它们是从直接丢弃的副本中创建的,所以你的c++编译器重用地址。这就是为什么你会得到"equal"迭代器,至少我是这么认为的。
你意识到你把事情比较错了吗?如果比较a == b
,即使写
cout << "a is different from b: " << (a==b) << endl;
输出将判断两个元素是否相同而不是不同。要检查两个东西是否不同,请使用!=
而不是==
。
这样做的原因是比较引用不同容器中的元素的两个迭代器是未定义的行为。所以,不能保证你会得到什么。这是因为getMyIntVec
返回_MyIntVec
的一个副本,而您将这些副本赋值给vector<int>
的新实例,因此它们确实是_MyIntVec
成员的两个不同副本的迭代器。
按标准:
§24.2.1
当且仅当存在有限的应用序列时,从迭代器i调用迭代器j可达表达式++i使i == j。如果j可以从i到达,则它们指向同一序列的元素。
和稍晚一点的标准:
§24.2.5
正向迭代器的==域是遍历相同底层序列的迭代器的域。
这个问题已经给出了答案
你这里有一个严重的逻辑问题:
cout << "The beginnings of the vectors are different: "
<< (fooOne.getMyIntVec().begin() == fooTwo.getMyIntVec().begin()) << endl;
如果它们相等,它将输出1而不是你通常期望的0。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?