在 ostream 中使用迭代器失败
using iterator in ostream fails
我正在尝试实现一个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() << " studentsn";
// 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;
}
students[i] = pos;
应改为
students[i] = *pos;
因为您要复制迭代器引用Student
,而不是迭代器本身。
但是为什么是动态的Student
数组而不是std::vector<Student>
?当前您有内存泄漏,因为您没有delete[] students;
编辑 1
删除。
编辑 2
除此之外,我只能看到它错了,就是眼前的std::
缺失。
sort (students, students+section.getNumberOfStudents());
这是假设没有使用自定义sort
方法。
编辑 3
在这里脱轨:
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
指针。
正如其他人所说,错误是因为您在填充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() << " studentsn";
// 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;
}
感谢您的所有回答。最终成为一个更基本的问题。我必须实现部分迭代器以返回学生迭代器。
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();
}
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- C++,弹出调试断言失败窗口,我得到矢量迭代器不兼容的错误运行时
- 为什么在此代码中隐式转换为常量迭代器失败?
- 映射/集迭代器不可取消引用 (C++) - 调试断言失败
- 断言失败:列出迭代器不可递增(不在循环中)
- 如果容器不是调用函数中的引用,则使用 std::thread 传递对迭代器的引用将失败
- C++迭代器作为 lambda 函数中的参数,断言失败:"vector iterators incompatible"
- 为什么后缀失败并且前缀在传递迭代器作为参数并在尾部位置递归时工作正常
- 在 ostream 中使用迭代器失败
- 断言失败,列表迭代器不可取消引用
- 简单迭代器适配器的模板匹配失败
- c++ 中带有容器迭代器的循环类型依赖关系(GCC 失败,而 MSVC 正常)
- 调试断言失败映射/设置迭代器不可取消引用
- 调试断言失败-矢量迭代器不可取消引用
- C++/OpenCV-从迭代器接收的字符串的VideoCapture失败
- 列出迭代器不兼容断言失败
- 调试断言失败:迭代器无效
- 调试断言失败的c++deque迭代器不可取消引用
- 迭代器结束检查在“for”循环内递增后失败
- 调试断言失败!表达式列表迭代器不兼容