为什么我无法使用find设置元素的迭代器?

时间:2013-11-27 14:50:09

标签: c++ find set

我试图在set中找到对象,然后调用该对象方法。代码如下所示:

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

此方法在Expensemanager类中。 impl这里是指向内部类的指针,其中定义了clientsSet集(我在那里存储Client对象)。 addNewCategory()是Client类中的一个方法。

我在impl位置收到错误说:"Error 1 error C2662: 'void ExpenseManagerNamespace::Client::addNewCategory(const std::string &)' : cannot convert 'this' pointer from 'const ExpenseManagerNamespace::Client' to 'ExpenseManagerNamespace::Client &'"

有什么想法吗?

编辑: 内部类和构造函数:

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

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

2 个答案:

答案 0 :(得分:3)

集合的元素是不可变的,因为通常,更改它们会改变它们在集合中的排序位置。你的选择包括,大致增加的肮脏程度:

  • 使用map,将客户端数据拆分为不可变标识符和可变数据;
  • 删除元素并重新插入修改后的副本;
  • 声明可变数据mutable以及修改它的函数const;
  • 使用const_cast进行修改。

如果您确定修改不会影响其在集合中的位置,则最后两个只是一个选项,否则您将破坏该集合。

此外,在尝试访问客户端之前,请不要忘记检查客户端是否已找到(即find未返回clientsSet.end())。

答案 1 :(得分:0)

在C ++ 11中,std::set::find有一个返回const_iterator的重载。它似乎是调用重载而不是返回iterator的版本,因此当您尝试更改数据时,您将收到const错误。

这可能与更严格的强制执行有关,因为在集合中创建值的行为类似于键(例如,不可变)。可以找到相关问题here

基本上,如果要修改元素,则应将其从集合中删除,修改并重新插入,除非您完全确定更改不会影响集合的比较。如果您确定更改不会破坏您的设置,则可以使用const_cast授予您对该元素的写入权限。