如何遍历集合C ++的所有元素

时间:2014-09-16 13:08:55

标签: c++

[更新:我的问题解决了!非常感谢Mike Seymour和Niall以及所有人!]

我的代码在for循环中有错误,我不知道如何解决它:(

MyClass::ITECH7603Class(set<Student>* students) {
    /* Initialize dynamically the group field */
    group = new map<string, Student>();

    for (set<Student>::iterator it = students->begin(); it != students->end(); it++) {
        addStudent(it);
    }
}

void MyClass::addStudent(Student* studentPtr) {
    string fullName = studentPtr->getName() + " " + studentPtr->getSurname();
    group->insert(pair<string, Student>(fullName, *studentPtr));
}

因此,主要思想是遍历集合中的所有学生,并将每个学生添加到地图组中。有帮助吗?非常感谢你!

4 个答案:

答案 0 :(得分:5)

for (set<Student>::iterator it = students->begin; it != students->end; it++) {
    addStudent(it);
}

应该是:

for (set<Student>::iterator it = students->begin(); it != students->end(); it++) {
                                               //^^                   //^^
    addStudent(it);
}

答案 1 :(得分:1)

addStudent使用指针,而it是迭代器,因此无法直接传递。

您应该更改addStudent以获取const的值或指针/引用:

// option 1
void addStudent(Student);
addStudent(*it);

// option 2
void addStudent(Student const &);
addStudent(*it);

// option 3
void addStudent(Student const *);
addStudent(&*it);

如果正如你在评论中所说的那样,你必须让它采用可变指针,那么你需要一些怪诞来处理这个集合的元素是不可变的这一事实:

// nasty option
addStudent(const_cast<Student*>(&*it));

// slightly less nasty option
Student copy = *it;
addStudent(&copy);

请注意,如果函数使用狡猾的指针对存储在集合中的Student对象进行任何修改,则第一个选项将给出未定义的行为。第二个是临时副本,可以在不破坏集合的情况下进行修改。只要addStudent只存储传递给它的对象的副本,而不是指针本身,只有copy被销毁时,它才会变为无效。

答案 2 :(得分:1)

在c ++ 11中,您可以使用range for sytax:

for (const auto &student : *students)
{
    addStudent(it);
}

然后更改addStudent函数签名以接受引用:

void MyClass::addStudent(const Student &student) {

答案 3 :(得分:0)

虽然您已经得到了“修复”代码的答案,以便编译和生成您显然可以接受的结果,但我发现它们在代码风格方面并不令人满意。我会以不同的方式完成这项工作。特别是,我执行此操作的代码不会有单个(显式)循环。如果我需要做大概你要求的东西,我可能会使用这样的代码:

std::pair<std::string, Student> make_mappable(Student &stud) { 
    return std::make_pair(stud.getName() + " " + stud.getSurName(), stud);
}

std::map<std::string, Student> gen_map(std::set<Student> const &input) { 
    std::map<std::string, Student> ret;
    std::transform(input.begin(), input.end(), 
                   std::inserter(ret, ret.end()), 
                   make_mappable);
    return ret;
}

肯定会有任何new,也不会有任何指向Student的指针。

OTOH,因为您用作map的密钥的数据是已经在集合中的项目中的数据,所以可以更方便地继续使用集合,并且只需指定一个基于学生姓名的比较功能:

struct by_given_name {
    bool operator()(Student const &a, Student const &b) const { 
        if (a.getName() < b.getName())
            return true;
        if (b.getName() < a.getName())
            return false;
        return a.getSurName() < b.getSurName();
    }
};

std::set<Student, by_given_name> xform(std::set<Student> const &in) { 
    return std::set<Student, by_given_name>{in.begin(), in.end()};
}

它的价值,后者的Live Demo

后者是否实用通常取决于另一个因素:您只能从名字/姓氏创建Student的能力。如果你不能这样做,按名称搜索将是不方便的(充其量),所以你想使用地图。

我意识到这可能不是很多(如果有的话)帮助完全显然是一个班级的家庭工作 - 但即使你的班级阻止你实际上上交体面的代码,它似乎值得我至少尝试学习编写体面的代码以及它需要的东西。如果你确实通过了课程并找到了编写代码的工作,那么你可能宁愿你的同事也不想伤害你。