我如何改进这个迫使我声明成员函数 const 并声明变量可变的设计?
由于某种原因,我正在迭代 std::set
中的类的元素,并且希望稍微修改键,因为我知道顺序将保持不变。
std::set
上的迭代器是 const_iterators
,因为如果修改键,可能会导致顺序错误,从而导致集合损坏。但是我确信我的操作不会改变集合中元素的顺序。
目前,这是我的解决方案:
class Foo
{
public:
Foo(int a, int b): a_(a),b_(b) {}
~Foo(){}
bool operator < (const Foo& o) const { return this.a_ < o.a_ ; }
void incrementB() const { ++b_; } // <-- the problem: it is not const!
private:
const int a_;
mutable int b_; // <-- I would like to avoid this
}
void f()
{
std::set<Foo> s;
// loop and insert many (distinct on a_) Foo elements;
std::for_each(s.begin(), c.end(), [](const Foo& s) { s.incrementB(); }); // Foo must be const. iterators are const_iterators
}
您将如何修改它(我知道我可以使用 std::map 但我很好奇您是否可以建议其他选项)以删除 mutable 和 const?
谢谢
For some reason I am iterating over elements of a class in an std::set
and would like to slightly modify the keys, knowing that the order will be unchanged.
Iterators on std::set
are const_iterators
because if the key is modified, it might result in a bad order and therefore in set corruption. However I know for sure that my operations won't change the order of my elements in the set.
For the moment, here is my solution:
class Foo
{
public:
Foo(int a, int b): a_(a),b_(b) {}
~Foo(){}
bool operator < (const Foo& o) const { return this.a_ < o.a_ ; }
void incrementB() const { ++b_; } // <-- the problem: it is not const!
private:
const int a_;
mutable int b_; // <-- I would like to avoid this
}
void f()
{
std::set<Foo> s;
// loop and insert many (distinct on a_) Foo elements;
std::for_each(s.begin(), c.end(), [](const Foo& s) { s.incrementB(); }); // Foo must be const. iterators are const_iterators
}
How would you modify it (I know I could use an std::map
but I am curious whether you can suggest other options) to remove mutable and const?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能。为了容器的正确性,集合元素必须是 const:
它迫使您认识到关键部分需要是不可变的,否则数据结构不变量将被破坏。
如果您想保留在非关键部分中“表达”常量性的可能性,请将其分成对并将它们存储在映射中:
或者,更灵活:
You can't. Set elements are required to be const for container correctness:
It forces you to realize that the key part needs to be immutable, or the data structure invariants would be broken.
If you wanted to retain the possibility to 'express' const-ness in the non-key part, split it out into pairs and store them in a map:
or, more flexibly:
另一种选择是将 const_cast 转换为引用类型:
但正如 sehe 已经说过的,您不应该修改 set 的元素。
Another option is to
const_cast
to a reference type :But as sehe already said, you shouldn't modify set's elements.
一种可能是在 pimpl 中分解 Foo 的值部分。
编辑:但是说实话,您必须决定额外的间接级别是否有意义,否则您最好使用地图。
One possibility might be to factor out the value part of Foo in a pimpl.
EDIT: To be honest however you must decide if the extra level of indirection makes sense or you would be better off using a map.