2

メッセージは私が作ったクラスです。messageTimeOut(および他のいくつかの関数)に渡すメイン関数にそれらのセットがあります。itoratorを使用するmessageTimeOutでは、それらをループして、さまざまなメンバー関数にアクセスしています。ただし、イテレータが指すメッセージのconstメンバー関数にしかアクセスできません。const以外のメンバー関数にアクセスしようとすると、次のエラーが発生します。

「関数内'voidmessageTimeOut(threadParameters *)':main.cpp:74:33:エラー:'constMessage'を'void Message :: setTimedOut(bool)'の'this'引数として渡すと修飾子[-fpermissive]が破棄されます。 」</p>

const Messageオブジェクトの非constメンバー関数にアクセスできないことは理にかなっていますが、非constメンバー関数にアクセスしてメッセージを変更できるように、これを非constメッセージオブジェクトにするにはどうすればよいですか?ありがとう

私のコードの一部:

     [ . . . ]

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

3 に答える 3

10

できません。

std :: set内の要素は常に一定です。そうしないと、ユーザーがセットに属する要素を変更することで、セット内の順序を変更できるためです。

std :: setにはこれをチェックする方法がないため、呼び出した関数が順序を変更しないことは問題ではないことに注意してください。

これを修正する一般的な方法は、セットから要素を削除し、変更してから、再挿入することです。別の方法は、マップを使用することです。これにより、データの複製が必要になる可能性があります。

于 2012-05-19T04:18:44.387 に答える
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) {
     ^

したがって、セットを使用することは、ここで行う正しい決定ではないように見えます。

于 2012-05-19T04:17:34.770 に答える
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など)を作成する場合は、スレッドの同期の量を減らすことができます。

于 2012-05-21T12:45:14.560 に答える