我正在尝试实现一个std :: list来替换此赋值中的链表。我不允许更改声明,只能更改.cpp文件中的代码。在大多数情况下,我正在取得进展,但我在实施这个
时遇到了麻烦std::ostream& operator<< (std::ostream& out, const Section& section);
即当我尝试创建迭代器时它失败了。我在代码的其他地方使用了迭代器,所以我不明白它为什么在这里失败,我相信它是因为它是私有的,但我不是确定如何在不更改明确禁止的.h文件的情况下解决问题:
std::ostream& operator<< (std::ostream& out, const Section& section)
{
// 1. print the section header
out << setw(8) << left << section.getCourse()
<< setw(6) << left << section.getCallNumber();
out << ": " << section.getNumberOfStudents() << " students\n";
// 2. collect the students, sort, and print
Student* students = new Student[section.getNumberOfStudents()];
{
int i = 0;
for ( auto pos = section.students.begin();
pos != section.students.end(); pos++)
{
students[i] = pos;
++i;
}
}
sort (students, students+section.getNumberOfStudents());
for (int i = 0; i < section.getNumberOfStudents(); ++i)
out << " " << students[i] << "\n";
out << flush;
return out;
}
答案 0 :(得分:2)
students[i] = pos;
应改为
students[i] = *pos;
因为你想要复制Student
迭代器引用,而不是迭代器本身。
但为什么动态数组Student
而不是std::vector<Student>
呢?目前您有内存泄漏,因为您没有delete[] students;
移除。
除此之外,我可以看到错误的是
前面缺少std::
sort (students, students+section.getNumberOfStudents());
这假设没有使用自定义sort
方法。
离开这里:
students[i] = *pos;
将学生从list
复制到动态数组students
。这可能很昂贵,所以这里有另一种选择:
首先需要证明这一点:必须包括
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
最小的学生班
class Student
{
std::string name;
public:
Student(std::string inname):name(inname)
{
}
const std::string & getname() const
{
return name;
}
friend bool operator<(const Student & a, const Student &b)
{
return a.name < b.name;
}
};
最小的分类
class Section
{
public:
std::list<Student> students;
};
最小的外流操作员
std::ostream& operator<<(std::ostream& out, const Section& section)
{
std::vector
而不是数组,以及常量引用的向量,因此我们不必复制学生。
std::vector<std::reference_wrapper<const Student>> students;
将参考文献存储在vector
中。可能会使用std::copy
和std::back_inserter
进行单行调整,但是这样做有点太多了,无法吸收一个例子。
for (const auto & student: section.students)
{
students.push_back(std::ref(student));
}
对vector
std::sort(students.begin(), students.end());
打印vector
for (const auto & student: students)
{
out << student.get().getname() << " ";
}
return out;
}
和一个main
统治他们所有人并在黑暗中绑定他们
int main()
{
Section s;
s.students.emplace_front("Tom");
s.students.emplace_front("Dick");
s.students.emplace_front("Harry");
std::cout << s;
}
所有这些都是易于切割的粘贴块:
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
class Student
{
public:
std::string name; // this is me being lazy. name should be private
Student(std::string inname):name(inname)
{
}
const std::string & getname() const
{
return name;
}
friend bool operator<(const Student & a, const Student &b)
{
return a.name < b.name;
}
};
class Section
{
public:
std::list<Student> students;
};
std::ostream& operator<<(std::ostream& out, const Section& section)
{
std::vector<std::reference_wrapper<const Student>> students;
// store references in the `vector`.
for (const auto & student: section.students)
{
students.push_back(std::ref(student));
}
// Sort the `vector`
std::sort(students.begin(), students.end());
// print the `vector`
for (const auto & student: students)
{
out << student.get().getname() << " ";
}
return out;
}
int main()
{
Section s;
s.students.emplace_front("Tom");
s.students.emplace_front("Dick");
s.students.emplace_front("Harry");
std::cout << s;
}
或者做Remy建议并使用std::vector<Student *>
和自定义比较器取消引用std::sort
的指针。
答案 1 :(得分:1)
正如其他人所说,错误是因为在填充students[]
数组时你没有取消引用迭代器:
students[i] = pos; // <-- should be *pos instead!
我建议采用更快更有效的替代方法:
std::ostream& operator<< (std::ostream& out, const Section& section)
{
// 1. print the section header
out << setw(8) << left << section.getCourse()
<< setw(6) << left << section.getCallNumber();
out << ": " << section.getNumberOfStudents() << " students\n";
// 2. collect the students, sort, and print
std::vector<const Student*> students;
students.reserve(section.getNumberOfStudents());
for ( auto pos = section.students.cbegin();
pos != section.students.cend(); ++pos)
{
students.push_back(&(*pos));
}
sort (students.begin(), students.end(),
[](const Student *a, const Student *b) { return (*a < *b); }
);
for ( auto pos = students.cbegin();
pos != students.cend(); ++pos)
{
out << " " << *(*pos) << "\n";
}
out << flush;
return out;
}
答案 2 :(得分:0)
我感谢您的所有答案。结束是一个更基本的问题。我必须实现Section迭代器来返回学生迭代器。
Section::iterator Section::begin() {
return students.begin();
}
Section::const_iterator Section::begin() const {
return students.begin();
}
Section::iterator Section::end() {
return students.begin();
}
Section::const_iterator Section::end() const {
return students.begin();
}