迭代时 C++ 更改列表?

问题描述

C++11 中有一个名为 jobs 的列表,我想在其中删除所有停止标志为真的作业,所以我写道:

auto job = jobs.begin();
while (job != jobs.end()) {
    if (!job->stopped) {
        job = jobs.erase(job)
    } else {
        ++job;
    }
}

但是有人看了我的代码说这是错误的,我不明白为什么?

解决方法

如果不考虑与此语句中缺少的分号相关的拼写错误

job = jobs.erase(job)
                    ^^^

以及这种情况下的第二个错字

if (!job->stopped) {
    ^^^^

应该这样写

if ( job->stopped) {

(也就是说,您在编写所有带有设置标志 stopped 的作业时需要删除)您的代码是正确的,但是是多余的。

你可以直接写

jobs.remove_if( []( const auto &job ) { return job.stopped; } );

jobs.remove_if( []( const JobEntry &job ) { return job.stopped; } );

如果在成员函数中调用此语句。

编辑:这是一个使用您的类声明的演示程序。

#include <iostream>
#include <string>
#include <list>
#include <ctime>

typedef int pid_t;

class JobsList {
public:
    class JobEntry {
    public:
        pid_t pid,jid;
        std::string cmd;
        time_t in_time;
        bool stopped;

        JobEntry( int pid,int jid,const std::string &cmd,bool stopped )
            :pid( pid ),jid( jid ),cmd( cmd ),stopped( stopped )
        {}
        // TODO: Add your data members

        bool operator<( JobEntry const &tmp ) const {
            return jid < tmp.jid;
        }

        bool operator==( JobEntry const &tmp ) const {
            return jid == tmp.jid;
        }
    };
    std::list<JobEntry> jobs;
};

int main()
{
    JobsList jobs_list =
    {
        {
            { 1,1,"first",false },{ 2,2,"second",true }
        }
    };

    std::cout << jobs_list.jobs.size() << '\n';
    jobs_list.jobs.remove_if( []( const auto &job ) { return job.stopped; } );
    std::cout << jobs_list.jobs.size() << '\n';
}

为了简单起见,我只介绍了这个 typedef

typedef int pid_t;

并更改了构造函数中的参数声明

JobEntry( int pid,bool stopped )
                            ^^^^^^^