无法访问C ++ std :: set中对象的非const成员函数

时间:2012-05-19 04:05:15

标签: c++ stl iterator set const

消息是我制作的课程。我在main函数中有一组它们传递给messageTimeOut(以及其他一些函数)。在使用itorator的messageTimeOut中,我循环遍历它们并访问不同的成员函数。但是,我只能访问迭代器指向的Message的const成员函数。如果我尝试访问非const成员函数,我会收到错误:

  

“在函数中'void messageTimeOut(threadParameters *)':   main.cpp:74:33:错误:将'const Message'作为'this'参数传递给   'void Message :: setTimedOut(bool)'丢弃限定符[-fpermissive]。“

有意义的是我无法访问const Message对象的非const成员函数,但是如何将其作为非const的Message对象,以便我可以访问非const成员函数并更改Message?感谢

我的部分代码:

     [ . . . ]

void messageTimeOut( threadParameters* params )
{
     set<Message>::iterator it = params->messages->begin();
     [ . . . ]
    for ( ; it != params->messages->end(); ++it )
    {
        if ( (it->createdTime() + RESPONSE_WAIT) < GetTickCount() ) 
        {
            it->setTimedOut(true); // error 
        }
    }
    ReleaseMutex(sentQueueMutex);
}

     [ . . . ]

int main()
{
    threadParameters rmparameters;
    set<Message> sentMessages;
     [ . . . ]


    rmparameters.logFile = &logFile;
    rmparameters.socket = socketDesciptor;
    rmparameters.messages = &sentMessages;
      [ . . . ]

    messageTimeOut( rmparameters );
      [ . . . ]

    return 0;
}

3 个答案:

答案 0 :(得分:9)

你不能。

std :: set中的元素总是不变的,因为否则用户可以通过修改属于该集合的元素来修改集合中的排序。

请注意,调用的函数不会改变排序并不重要,因为std :: set无法检查它。

解决此问题的常用方法是从集合中删除元素,修改它,然后重新插入。 另一种方法是使用地图,即使这可能会迫使你复制一些数据。

答案 1 :(得分:1)

您应该无法修改std :: set的内容。这是一个简化的测试用例:

#include <set>
#include <iostream>

void print(int & data) {}

int main() {
    std::set<int> objects;

    objects.insert(3);
    print(*objects.find(3));
}

Clang会报告以下错误:

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) {
     ^

因此,看起来使用集合不是正确的决定。

答案 2 :(得分:0)

集合中的对象是const意味着它们不可变。以下是一些选项

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.

其中我更喜欢3号。你试图改变消息的事实是“糟糕的代码味道”。如果您要避免所有更改数据而是创建新结构(例如std :: map),那么您可以减少线程同步的数量。