【问题标题】:Unable to access non-const member functions of objects in C++ std::set无法访问 C++ std::set 中对象的非常量成员函数
【发布时间】:2012-05-26 14:14:18
【问题描述】:

Message 是我创建的一个类。我在传递给 messageTimeOut (和其他一些函数)的主函数中有一组它们。在使用 itorator 的 messageTimeOut 中,我正在循环它们并访问不同的成员函数。但是,我只能访问迭代器指向的 Message 的 const 成员函数。如果我尝试访问非 const 成员函数,则会收到错误消息:

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

我无法访问 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;
}

【问题讨论】:

  • threadParameters的成员messages的声明类型是什么?

标签: c++ stl iterator set constants


【解决方案1】:

集合中的对象是 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),那么您可以减少线程同步的数量。

【讨论】:

    【解决方案2】:

    你不能。

    std::set 中的元素始终是常量,否则用户可以通过修改属于集合的元素来修改集合中的顺序。

    请注意,您调用的函数不会更改顺序并不重要,因为 std::set 无法检查这一点。

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

    【讨论】:

    • 谢谢。这就说得通了。我考虑过使用地图,但在构造对象之前我的密钥不存在,但我想我可以构造 Message 对象,然后将其复制到地图中。
    【解决方案3】:

    您不应该能够修改 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) {
         ^
    

    因此,看起来使用集合并不是在这里做出的正确决定。

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 2014-07-29
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 2013-12-26
      • 1970-01-01
      相关资源
      最近更新 更多