Marius
Marius

Reputation: 1101

Why am I unable to get iterator to set element with find?

I am trying to find object in set and then call that objects method. Code looks like this:

   void ExpenseManager::addCategory(const string &userName, const string &categName){
      Client temp(userName);
      impl->clientsSet.find(temp)->addNewCategory(categName);
   }

This method is in Expensemanager class. impl here is pointer to inner class, where clientsSet set is defined (I store Client objects in there). addNewCategory() is a method in Client class.

I get an error at impl position saying: "Error 1 error C2662: 'void ExpenseManagerNamespace::Client::addNewCategory(const std::string &)' : cannot convert 'this' pointer from 'const ExpenseManagerNamespace::Client' to 'ExpenseManagerNamespace::Client &'"

Any ideas?

EDIT: Inner class and contructor:

   class ExpenseManager::Implementation{
   private:
      set<Client> clientsSet;
      set<Client>::iterator clientPosSet;
      friend class ExpenseManager;
   };

   // Constructors/destructor-----------------------------------------------
   ExpenseManager::ExpenseManager()
      : impl(new Implementation()){
   }

Upvotes: 0

Views: 176

Answers (2)

Zac Howland
Zac Howland

Reputation: 15872

In C++11, std::set::find has an overload that returns a const_iterator. It appears to be calling that overload instead of the version that returns an iterator, so when you attempt to change the data, you are getting the const error.

The reason for that likely has something to do with more strict enforcement of making values in a set behave like keys (e.g. immutable). A related question can be found here.

Basically, if you want to modify an element, you should remove it from the set, modify it, and re-insert it, unless you can be absolutely sure that your change will not affect the comparison for your set. If you can be sure that the change will not break your set, you can use a const_cast to give you write-access to the element.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254431

Elements of a set are immutable since, in general, changing them will change their sort position within the set. Your choices include, in approximately increasing levels of nastiness:

  • Use a map, splitting the client data into an immutable identifier and mutable data;
  • Remove the element and reinsert a modified copy;
  • Declare the mutable data mutable and the function to modify it const;
  • Use const_cast to allow modification.

The last two are only an option if you're sure that the modification won't affect its position in the set, otherwise you will break the set.

Also, don't forget to check whether the client was found (i.e. that find didn't return clientsSet.end()) before trying to access it.

Upvotes: 3

Related Questions