C++;列表<;T>;如何插入元素? 我有一个关于C++列表的问题。下面是我不太明白的代码 #include <iostream> #include <list> #include <string> using namespace std; struct Customer { string firstName; string lastName; }; void replace(list<Customer>& customers, int index, Customer item) { std::list<Customer>::iterator it = customers.begin(); advance(it, index); *it = item; } Customer get (list<Customer>& customers, int index) { std::list<Customer>::iterator it = customers.begin(); advance(it, index); return *it; } int main() { list<Customer> customers; Customer c1; c1.firstName = "Jack"; c1.lastName = "Smith"; Customer c2; c2.firstName = "Jane"; c2.lastName = "Doe"; insert(customers, 50, c1); cout << get(customers,0).firstName << endl; //outputs Jack even though I inserted it at index 50 insert(customers, 49, c2); cout << get(customers,0).firstName << endl; //outputs Jane cout << get(customers,50).firstName << endl; //where did Jack go? return 0; } #包括 #包括 #包括 使用名称空间std; 结构客户{ 字符串名; 字符串lastName; }; 作废替换(列表和客户、内部索引、客户项目) { std::list::iterator it=customers.begin(); 推进(it、索引); *它=项目; } 客户获取(列表和客户,整数索引) { std::list::iterator it=customers.begin(); 推进(it、索引); 归还它; } int main(){ 列出客户名单; 客户c1; c1.firstName=“杰克”; c1.lastName=“史密斯”; 客户c2; c2.firstName=“简”; c2.lastName=“Doe”; 插入(客户,50,c1); cout

C++;列表<;T>;如何插入元素? 我有一个关于C++列表的问题。下面是我不太明白的代码 #include <iostream> #include <list> #include <string> using namespace std; struct Customer { string firstName; string lastName; }; void replace(list<Customer>& customers, int index, Customer item) { std::list<Customer>::iterator it = customers.begin(); advance(it, index); *it = item; } Customer get (list<Customer>& customers, int index) { std::list<Customer>::iterator it = customers.begin(); advance(it, index); return *it; } int main() { list<Customer> customers; Customer c1; c1.firstName = "Jack"; c1.lastName = "Smith"; Customer c2; c2.firstName = "Jane"; c2.lastName = "Doe"; insert(customers, 50, c1); cout << get(customers,0).firstName << endl; //outputs Jack even though I inserted it at index 50 insert(customers, 49, c2); cout << get(customers,0).firstName << endl; //outputs Jane cout << get(customers,50).firstName << endl; //where did Jack go? return 0; } #包括 #包括 #包括 使用名称空间std; 结构客户{ 字符串名; 字符串lastName; }; 作废替换(列表和客户、内部索引、客户项目) { std::list::iterator it=customers.begin(); 推进(it、索引); *它=项目; } 客户获取(列表和客户,整数索引) { std::list::iterator it=customers.begin(); 推进(it、索引); 归还它; } int main(){ 列出客户名单; 客户c1; c1.firstName=“杰克”; c1.lastName=“史密斯”; 客户c2; c2.firstName=“简”; c2.lastName=“Doe”; 插入(客户,50,c1); cout,c++,list,insert,indexing,C++,List,Insert,Indexing,您的列表有0个元素。请尝试调用customers.size() 因此,std::advance返回customers.end(),这是无效的迭代器。通过取消对它的引用,您将得到异常或UB,具体取决于您的构建选项 当我直接在索引50处插入项时,为什么这个示例没有崩溃 因为未定义的行为不一定会导致崩溃 您没有在索引50处插入。您正在使用一个超过结束迭代器(不能增加)的迭代器,然后尝试将其增加50倍;然后通过取消引用最终使用的完全无效的迭代器,进一步进入未定义的行为 GNU库将list实现为一个循环列

您的列表有0个元素。请尝试调用
customers.size()

因此,
std::advance
返回
customers.end()
,这是无效的迭代器。通过取消对它的引用,您将得到异常或UB,具体取决于您的构建选项

当我直接在索引50处插入项时,为什么这个示例没有崩溃

因为未定义的行为不一定会导致崩溃

您没有在索引50处插入。您正在使用一个超过结束迭代器(不能增加)的迭代器,然后尝试将其增加50倍;然后通过取消引用最终使用的完全无效的迭代器,进一步进入未定义的行为

GNU库将
list
实现为一个循环列表,其中一个虚拟节点充当“过去的结束”因此,在这个实现中,递增一个结束迭代器将返回到列表的开头,取消引用它将导致可访问的内存,因此不会出现崩溃。您只需写入该伪元素,然后覆盖它

当您执行无效操作时,其他实现的行为可能会有所不同

指数0-49的点会发生什么变化

它们不存在,因为你从不把任何东西放在清单上

在insert()和get()方法中,根据列表的大小检查索引并确保它们不通过列表边界是否正确


是的。
advance
不会检查序列的结尾,因为它无法知道那是什么。如果您尝试前进到结尾之外,您将得到未定义的行为,因此首先由您检查。

未定义的行为,在您将迭代器前进到
end()之外的位置
。这意味着程序可以执行任何操作,包括不崩溃和执行所看到的操作。此外,插入操作不会插入项目,而是在给定位置替换项目。将方法名称从insert()更改为replace(),错过了那个。所以正确的做法是手动检查传入的索引是否在预期范围内?谢谢您的回答和解释。