Unable to access non-const member functions of objects in C++ std::set

后端 未结 3 1866
后悔当初
后悔当初 2020-12-07 04:32

Message is a class I made. I have a set of them in the main function that I pass to messageTimeOut (and some other functions). In messageTimeOut using an itorator I am loopi

相关标签:
3条回答
  • 2020-12-07 04:58

    You shouldn't be able to modify the contents of a std::set. Here's a reduced test case:

    #include <set>
    #include <iostream>
    
    void print(int & data) {}
    
    int main() {
        std::set<int> objects;
    
        objects.insert(3);
        print(*objects.find(3));
    }
    

    Clang would report the following errors:

    blah.cc:14:2: error: no matching function for call to 'print'
            print(*objects.find(3));
            ^~~~~
    blah.cc:4:6: note: candidate function not viable: 1st argument ('const int') would lose const qualifier
    void print(int & data) {
         ^
    

    Therefore, it looks like using a set is not the correct decision to be made here.

    0 讨论(0)
  • 2020-12-07 05:02

    You can't.

    Elements inside an std::set are always constant, because otherwise an user could modifiy the ordering in the set by modifying an element which belong to the set.

    Notice that it doesn't matter that the function that you invoke doesn't change the ordering, since std::set has no way to check this.

    A common way to fix this is to remove the element from the set, modify it, then reinsert it. Another way would be to use a map, even if this would probably force you to duplicate some data.

    0 讨论(0)
  • 2020-12-07 05:02

    Objects in a set are const meaning that they are not mutable. Here are some options

    1) Create copies of the messages in a new set
    2) Remove the messages, mutate them, and put them back.
    3) Remove the "timeout" field from the message.
    

    Of these I prefer number 3. The fact that you are trying to mutate the messages is a "bad code smell". If you were to avoid all changing of data and instead create a new structure (for example a std::map) then you could reduce the amount of thread synchronization.

    0 讨论(0)
提交回复
热议问题