【问题标题】:Change the list item更改列表项
【发布时间】:2014-11-10 08:53:03
【问题描述】:

对不起我的英语。

某类:

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变量的指针。

【问题讨论】:

  • 为什么Kid 包含“可爱的孩子”列表?一个孩子就是一个孩子。一个孩子不包含其他孩子。这毫无意义。您也有间接级别的问题。给定std::list&lt;Kid&gt; kids;kids.push_back(new kid("xxx"); 无法编译--new 给出了一个指针,但您试图将该指针作为它所引用的对象插入。
  • 奇怪的是你有std::list&lt;Kid&gt; kids;,然后你使用new添加新的kids:kids.push_back(new Kid("Jeck"));...
  • _cuteKids - 是一个爱孩子的孩子名单。这份工作,它不会改变。

标签: c++ list foreach containers std


【解决方案1】:

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

做你想做的事,把e作为参考:

for (auto &e : kids)

【讨论】:

    【解决方案2】:

    在您的代码中:

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

    您正在对kids 容器中的每个项目进行副本,同时迭代容器本身,因为您错过了一个“简单” &amp;

    因此,e._cuteKids.push_back(...); 语句在副本上运行,不是在原始项目上运行。这个本地副本在每次循环迭代后“蒸发”kids 容器中的原始项目不受影响

    您必须正确地使用 references (&amp;) 对原始项目进行迭代,以避免这些本地深层副本:

    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' ...
    }
    

    不会引入细微的错误,例如忘记&amp;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多