我如何改进这种设计,迫使我声明一个成员函数const和声明变量可变? [英] How can I improve this design that forces me to declare a member function const and declare variables mutable?

查看:128
本文介绍了我如何改进这种设计,迫使我声明一个成员函数const和声明变量可变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某种原因,我在 std :: set 中的一个类的元素上进行迭代,并希望轻微修改键,知道顺序将不会改变。

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.

std :: set 上的迭代器是 const_iterators 如果密钥被修改,它可能导致一个坏的顺序,因此在设置损坏。但我知道我的操作不会改变我的元素在集合中的顺序。

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
}

如何修改它(我知道我可以使用 std :: map 但我很好奇是否可以建议其他选项)删除mutable和const?

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?

/ p>

Thanks

推荐答案

你不能。 Set元素需要为容器正确性的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.

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<
};

如果你想保留在非关键部分表达常量的可能性,将它分成对,并将它们存储在映射中:

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:

std::map<std::string /*key_part*/, int /*m_cached*/> mapped;

或更灵活:

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;

这篇关于我如何改进这种设计,迫使我声明一个成员函数const和声明变量可变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆