由于某种原因,我正在迭代一个类的元素,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
}
Run Code Online (Sandbox Code Playgroud)
你会如何修改它(我知道我可以使用std::map但我很好奇你是否可以建议其他选项)来删除mutable和const?
谢谢
你不能.容器正确性要求set元素为const:
它迫使您意识到关键部分需要是不可变的,否则数据结构不变量将被破坏.
struct element
{
std::string key_part; // const in the set
bool operator<(const element&o) const { return key_part<o.key_part; }
private:
mutable int m_cached; // non-key, *NOT* used in operator<
};
Run Code Online (Sandbox Code Playgroud)
如果你想保留在非关键部分"表达"常量的可能性,可将其拆分成对并将它们存储在地图中:
std::map<std::string /*key_part*/, int /*m_cached*/> mapped;
Run Code Online (Sandbox Code Playgroud)
或者,更灵活:
struct element
{
std::string key_part; // const in the set
bool operator<(const element&o) const { return key_part<o.key_part; }
struct value {
int m_cached;
int m_moredata; //...
} /*not in the element itself*/;
};
std::map<element, element::value> mapped;
Run Code Online (Sandbox Code Playgroud)