更改列表项

时间:2014-09-16 14:34:17

标签: c++ list foreach containers std

抱歉我的英文。

某些课程:

class Kid {
public:
    ...
    string _name;
    std::list<string> _cuteKids;
};

使用课程:

    std::list<Kid> kids;
    kids.push_back(new Kid("Jeck"));
    kids.push_back(new Kid("Anna"));
    kids.push_back(new Kid("Toma"));

    for(auto e: kids) {

         e._cuteKids.push_back("Jeck"); // Many some names...
         [1]
    }
    [2]

如果您查看调试器中的代码,第1段中的列表 _cuteKids - 都有项目。但如果查看第2段中的列表 _cuteKids - 没有项目。为什么呢?

这只是一个例子,实际上我的算法很复杂,但最重要的是在循环 _cuteKids 变空之后。好像它是一个静态变量(e:kids),而不是指向 kids 变量的指针。

2 个答案:

答案 0 :(得分:4)

e是列表项的副本,因此对其进行更改不会影响列表中的项目。

要做你想做的事,请将e作为参考:

for (auto &e : kids)

答案 1 :(得分:1)

在您的代码中:

for (auto e: kids) {
    e._cuteKids.push_back("Jeck"); // Many some names...
}

您正在对kids容器中的每个项目执行副本,同时迭代容器本身,因为您错过了&#34;简单&#34; &

因此,声明e._cuteKids.push_back(...);正在原始项目的副本上运行。每次循环迭代后,本地副本&#34;蒸发&#34; kids容器中的原始项目不受影响

您必须使用引用&)正确迭代原始项目,以避免这些本地深层副本:

for (auto& e : kids) {
    // ... do something on 'e' ...
}

请注意,有一个基于基于范围的for循环(N3994)的提案,它可能是该语言下一次迭代的一部分(C ++ 17?),避免代码中的错误:

  

Range-Based For-Loops: The Next Generation (Revision 1)

使用这个新提出的语法,可以简单地写:

for (e : kids) {
    // ... do something on 'e' ...
}

没有引入遗忘,例如忘记&