2

I have a class containing a std::set of objects which have names. The names are used to order the objects in the set. I can find the objects in the set by name, but I cannot modify them using the iterator returned by std::set::find() The code fails compilation when I try, like this:

class cTestObject
{
public:
    cTestObject( const string& name )
        : myName( name )
    {

    }

    void Add( int i )
    {}

    void constAdd( int i ) const
    {}

    bool operator<( const cTestObject& m2) const
    {
        return myName < m2.myName;
    }

private:
    string myName;
};

class cTestContainer
{
public:
    void Method();
private:
       set < cTestObject > mySet;
};

void cTestContainer::Method()
{
    // declare set iterator which is NOT constant
    std::set<cTestObject>::iterator it;

    it = mySet.find(  cTestObject("test") );
    if( it != mySet.end() )
    {

        it->constAdd( 1 );    // compiles OK


        it->Add( 1 );    // fails to compile
    }

}

The compiler says:

error: passing 'const cTestObject' as 'this' argument
   of 'void cTestObject::Add(int)' discards qualifiers [-fpermissive]|

As the accepted answer to the duplicate question says: "You can't" Instead, copy the object, modify it, erase the original, and insert the modified copy. Like this:

        cTestObject T( *it );
        T.Add( 1 );
        mySet.erase( it );
        mySet.insert( T );
ravenspoint
  • 19,093
  • 6
  • 57
  • 103
  • Not very clean, but you could change method to `Add() const` and make the data that `Add()` operates on, `mutable`. Aslong as you don't modify the key (`myName`) this would be safe. Despite not being "clean" it might have a valid use if performance is an issue and it would be expensive to "copy the object, modify it, erase the original, and insert the modified copy". – zett42 Mar 04 '17 at 18:50

0 Answers0