c++ - 我从 std::set 得到 const_iterator 而不是迭代器
问题描述
我有以下根本无法编译的代码。它说我不能转换const Node
为Node&
但Node
不是const
也不是A
指方法const this
也不std::set
是 const。
我哪里错了?
#include <set>
#include <string>
struct Node
{
std::string name;
};
struct NodeNameComparator
{
using is_transparent = void;
bool operator()(const Node &a, const std::string &b) const { return a.name < b; }
bool operator()(const std::string &a, const Node &b) const { return a < b.name; }
bool operator()(const Node &a, const Node &b) const { return a.name < b.name; }
};
struct A
{
std::set<Node, NodeNameComparator> nodeset;
Node &add_or_get_node(const std::string &name)
{
std::set<Node, NodeNameComparator>::iterator it = nodeset.template find(name);
// IT WORKS BUT IT IS A WORKAROUND.
//return it == nodeset.end() ? const_cast<Node&>(*(nodeset.insert(*new Node{name}).first)) : const_cast<Node&>(*it);
//ERROR!!!
return it == nodeset.end() ? *(nodeset.insert(*new Node{name}).first) : *it;
};
};
int main() { return 0; }
解决方案
std::set
不仅仅是一组元素,它是一组有序的独特元素。的元素在std::set
设计上是不可变的,因此您不能通过std::set
修改其元素来破坏不变性。这就是为什么std::set::iterator
和std::set::const_iterator
都是常量迭代器的原因。
Cppreferencestd::set
读取:
Member type Definition
iterator Constant LegacyBidirectionalIterator
const_iterator Constant LegacyBidirectionalIterator
另请参阅此 LWG 问题:
关联容器中的键是不可变的。...对于值类型与键类型相同的关联容器,两者
iterator
都是const_iterator
常量迭代器。基本原理: ...如果元素是可变的,则没有编译时方法来检测导致修改排序的简单用户疏忽。有报道说这实际上发生在实践中,诊断起来很痛苦。如果用户需要修改元素,可以使用可变成员或
const_cast
.
推荐阅读
- ruby-on-rails - 保存后未更新父级的rails has_many关系
- python - astropy Tables ascii 输出的简单格式化
- discord.js - 在嵌入中提及
- delphi - DFM 文件中的属性顺序是否重要?
- angular - 如何使用管道将货币汇率转换为选定的货币类型?
- mongodb - Amazon DocumentDB 是否支持 BI 连接器?
- excel - 如何使用列名在 Excel 过滤表中选择多个不相邻的列
- ios - SwiftUI - “文本”类型的值没有成员“颜色”错误
- java - fastxml.jackson.databind 无效定义异常
- javascript - 从 JQuery.post() 中恢复数据