列表::迭代器对于移动到列表无效? 我使用了相当数量的C++,但是没有太多代码< STD::列表< /代码>。 在我当前的项目中,我需要一个std::list数据成员,并使用std::list::iterator跟踪列表中的某个位置。对象也必须是可移动的,但是在我的例子中,默认的移动构造函数是不可能的。这里std::list做了一些让我吃惊的事情

列表::迭代器对于移动到列表无效? 我使用了相当数量的C++,但是没有太多代码< STD::列表< /代码>。 在我当前的项目中,我需要一个std::list数据成员,并使用std::list::iterator跟踪列表中的某个位置。对象也必须是可移动的,但是在我的例子中,默认的移动构造函数是不可能的。这里std::list做了一些让我吃惊的事情,c++,list,iterator,move-semantics,C++,List,Iterator,Move Semantics,考虑 #include <list> #include <vector> #include <iostream> #include <algorithm> using namespace std; template<typename T> void test() { T l { 1, 2, 3, 4, 5 }; cout << "l = "; for(const auto& e:

考虑

#include <list>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

template<typename T>
void test() {
    T l { 1, 2, 3, 4, 5 };
    cout << "l = "; for(const auto& e: l) cout << e << " "; cout << endl;
    auto pos = find(l.begin(), l.end(), 6);
    if (pos == l.end()) cout << "l end\n";

    cout << "---- moving l > lmv ----" << endl;
    T lmv { std::move(l) };
    cout << "l = "; for(const auto& e: l) cout << e << " "; cout << endl;
    cout << "lmv = "; for(const auto& e: lmv) cout << e << " "; cout << endl;
    if (pos == l.end()) cout << "l end\n";
    if (pos == lmv.end()) cout << "lmv end\n";
}

int main() {
    cout << "___vector___\n";
    test<vector<int>>();
    cout << "___list___\n";
    test<list<int>>();
}
也就是说,指向从
列表
s端移动的迭代器不指向移动到
列表
s端。 但它对向量是有效的,如果迭代器本质上是指针,这就是我一直期望的。为什么
列表
不同?元素的内存位置不应随移动而改变。。
list
s是否移动更改列表迭代器?为什么?

我使用的是“g++.exe(Rev1,由MSYS2项目构建)10.2.0”
在Windows 10上的MSYS2下

如果您在测试函数末尾添加了这样可怕的行 (这是完全错误的,消毒剂会侮辱你!), 您可以在
向量的情况下看到
end()
迭代器 指定超过缓冲区结尾的内容,该缓冲区包含 存储的元素,但如果是
列表
结束迭代器 指定存储在
列表中的某种标记
结构本身

然后,在移动之后,向量的缓冲区仍然是相同的 但是它不再属于
l
,因此地址超过了末尾 对于
lmv
,此缓冲区的长度相当于
end()

另一方面,在移动
列表后,
pos
指定
l
中的地址仍然指定相同的地址(尽管
l
已从中移动),但未指定内部的
end()
标记
lvm
在初始化
pos
时甚至不存在


移动容器时应保留迭代器

但是,容器的迭代器不指向元素,因此允许使用

如果您将代码更改为使用
开始
而不是
结束
,则它可以工作

#包括
#包括
#包括
#包括
使用名称空间std;
样板
无效测试(){
tl{1,2,3,4,5};

难道你的程序不能用一个
assert()来彻底崩溃吗当在VisualC++中运行,调试模式。也比较指向不同容器的迭代器没有意义。@根据代码中的迭代器,在ST>::列表< /COD>中的某个程序员在移动之后是有效的,尽管对于代码< >结束< /代码>迭代器,它可能是一个例外。invalidated@Daniel兰格一号如果容器确实不同,我会同意,但这是一个动作……我明白了……谢谢。我意识到测试函数结束时的恐惧——这基本上只是为了看一些东西,因为我不知道发生了什么。
___vector___
l = 1 2 3 4 5 
l end
---- moving l > lmv ----
l = 
lmv = 1 2 3 4 5 
lmv end
___list___
l = 1 2 3 4 5 
l end
---- moving l > lmv ----
l = 
lmv = 1 2 3 4 5 
l end
#include <list>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

template<typename T>
void test() {
    T l { 1, 2, 3, 4, 5 };
    cout << "l = "; for(const auto& e: l) cout << e << " "; cout << endl;
    auto pos = find(l.begin(), l.end(), 1);
    if (pos == l.begin()) cout << "l begin\n";

    cout << "---- moving l > lmv ----" << endl;
    T lmv { std::move(l) };
    cout << "l = "; for(const auto& e: l) cout << e << " "; cout << endl;
    cout << "lmv = "; for(const auto& e: lmv) cout << e << " "; cout << endl;
    if (pos == l.begin()) cout << "l begin\n";
    if (pos == lmv.begin()) cout << "lmv begin\n";
}

int main() {
    cout << "___vector___\n";
    test<vector<int>>();
    cout << "___list___\n";
    test<list<int>>();
}