更改列表项

Change the list item

本文关键字:列表      更新时间:2023-10-16

对不起我的英语。

某些类别:

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-have项。但是,如果查看第2段中的列表_cuteKids,则没有项目。为什么?

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

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

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

for (auto &e : kids)

在您的代码中:

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

您正在对kids容器中的每个项执行复制,同时迭代容器本身,因为您错过了"简单"&

因此,语句e._cuteKids.push_back(...);操作的是副本,而不是原始项上的。此本地副本在每次循环迭代后"蒸发",并且kids容器中的原始项不受影响。

您必须使用引用&)对原始项进行正确迭代,以避免这些本地深度复制:

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

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

基于范围的环路:下一代(修订版1)

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

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

而不会引入诸如忘记CCD_ 9之类的细微错误。