【发布时间】:2015-01-17 16:21:16
【问题描述】:
我重载了 operator-=() 以从指针向量中删除元素(指针是唯一的,因此无需删除所有出现,一旦指针被擦除,循环就可以终止):
Rooms& Rooms::operator-=(Course *c) {
for (Iter i = rooms.begin(); i != rooms.end(); ++i) {
if (**i == *c) {
*i = NULL;
i = rooms.erase(i);
break;
}
}
return *this;
}
问题是,在应用到向量之后,我得到了向量最后一个元素的重复指针。之前:
-------------------------------------------------------------------
| POL | CAE | RUS | ENG | BUS | JPY | | | | | |
| G 1 | G 1 | G 2 | G 2 | G 2 | G 2 | | | | | |
| 9 | 9 | 10 | 10 | 10 | 10 | | | | | |
移除 ENG & BUS 后:
-------------------------------------------------------------------
| POL | CAE | RUS | JPY | JPY | JPY | | | | | |
| G 1 | G 1 | G 2 | G 2 | G 2 | G 2 | | | | | |
| 9 | 9 | 10 | 10 | 10 | 10 | | | | | |
应该改变什么才能真正得到结果:
-------------------------------------------------------------------
| POL | CAE | RUS | JPY | | | | | | | |
| G 1 | G 1 | G 2 | G 2 | | | | | | | |
| 9 | 9 | 10 | 10 | | | | | | | |
任何帮助将不胜感激。
编辑:
我的打印功能是这样的:
std::ostream& operator<<(std::ostream& out, const Rooms& rs) {
std::vector<std::string> output(3);
std::ostringstream temp;
for (int i = 0; i < rs.rooms.capacity(); ++i) {
if (rs.rooms[i]) {
temp << "| " << rs.rooms[i]->getCode() << " ";
output[0] += temp.str();
temp.str("");
temp << "| G" << std::setw(CODE_LENGTH - 1)
<< rs.rooms[i]->getGroup() << " ";
output[1] += temp.str();
temp.str("");
temp << "| " << std::setw(CODE_LENGTH)
<< rs.rooms[i]->getSize() << " ";
output[2] += temp.str();
temp.str("");
} else {
output[0] += "| ";
output[1] += "| ";
output[2] += "| ";
}
}
output[0] += "|";
output[1] += "|";
output[2] += "|";
out << printHorizont(rs.size) << output[0] << std::endl
<< output[1] << std::endl << output[2] << std::endl;
return out;
}
看起来很复杂,但找不到更好的打印方式。
【问题讨论】:
-
为什么这样:
i =rooms.erase(i); ? -
@Haketo 被擦除的迭代器失效。
erase将一个有效的迭代器返回到曾经位于被擦除元素后面的元素。 OP:如果两个可擦除元素直接出现在彼此之后,此代码将跳过元素,但它应该缩短向量。在这一切之后使用向量的代码是否有可能不检查更改的长度? -
@Haketo 否则我在打印结果时遇到分段错误。在打印功能中,我使用 rooms[i] 来访问元素。
-
请说明你是如何调用函数的?你怎么知道你得到了重复的条目?
-
@AndrzejSmyk - 问题是您应该使用诸如
find_if、remove_if等算法函数,而不是像这样的循环。那么你的错误一般不会发生。