【问题标题】:c++ change object properties of object that is key in map?c ++更改地图中关键对象的对象属性?
【发布时间】:2021-12-03 00:50:39
【问题描述】:

假设我有以下课程:

#include <string>

class Item {
public: 
   Item(std::string name, int id);
   virtual int getWeight() = 0;

protected:
   std::string name;
   const int id;
}
#include <vector>
#include <memory>
#include "Item.h"

class Bucket : Item { 
public:
    Bucket(std::string name, std::string type, int id) // In the implementation this will call the Constructor of Item
    bool operator<(const Bucket& b) const {
        return (id < b.id );
    }
    void addItem(std::shared_ptr<Item> itemm) {
      this->weight += item->getWeight();
      this->items.push_back(item);
    }
    int getWeight() override; //this implementation does not matter to the problem

private:
    std::string type;
    std::vector<std::shared_ptr<Item>> items;
    int weight = 0;

}

还有其他类继承自类 Item,但为了更容易,我只显示类 Bucket。

现在在我的 main 方法中,我想遍历一个已经包含一些条目的映射并调用一个方法来更改键对象的一个​​属性。 main.cpp:

#include <map>
#include <memory>
#include <vector>
#include "Item.h"
#include "Bucket.h"

using namespace std;

int main(){
   map<Bucket, vector<shared_ptr<Item>>> map; // Imagine this map has some entries
   for(auto itr = map.begin(); itr != map.end(); itr++){
        for_each(itr->second.begin(), itr->second.begin(), [&itr](shared_ptr<Item> item){
            itr->first.addItem(item); // This does not compile, the error will be in the text below
        });

}

正如代码中所述,它不会在itr-&gt;first.addItem(item); 行编译并出现以下错误: 'this' argument to member function 'addItem' has type 'const Bucket', but function is not marked const.

我无法将方法设为 const,因为它正在更改对象的某些属性,并且我会在此处出现错误。 我不确定我是否正确理解了这个错误,但我认为问题在于,当我将 Bucket 放入地图时(Bucket 是关键),它变成了const。 如果是这种情况,有没有办法告诉编译器只使用 Bucket 的 id 属性作为映射的 const 键(而不将映射更改为 map&lt;int, &lt;pair&lt;Bucket,vector&lt;shared_ptr&lt;Item&gt;&gt;&gt;&gt;&gt; 之类的东西)?还是我不理解这里的主要问题?

【问题讨论】:

  • 通常这意味着更好的设计是可能的。 id 可能不应该是 Item 的一部分,即您的“将地图更改为类似 map”的评论可能是正确的方法。如果您真的想要解决方法,请查看here
  • 谢谢,那篇文章实际上是我一直在寻找但没有找到的东西。我可能会按照您的建议更改设计。
  • 使用const_cast怎么样?类似const_cast&lt;Bucket&amp;&gt;(itr-&gt;first).addItem(item);.

标签: c++ hashmap c++17 shared-ptr


【解决方案1】:

我认为问题在于,当我将 Bucket 放入地图时(Bucket 是关键),它变成了const

正确。映射应该是有序的,如果你能够改变一个键,你可以打破这个不变量。这样做可能会破坏所有后续搜索或严重插入。

链接的workaround 有效,但丑陋。除非 map-key-ness 是您的 Bucket 的核心功能(我无法从示例代码中判断这是否可能),否则让其某些成员 mutable 感觉就像是 hack。

你的整个设计看起来很奇怪,tbh - 你最终会得到一个充满Bucket 键的映射,这些键复制了键值对后半部分的信息。之后你打算将那些Buckets 移到其他地方,还是他们会永远被那些冗余引用的残留向量束缚住?

如果该映射是建立连接的中间步骤,则它不应该是 Bucket 对象所在的位置。也许您应该有一个主要查找map&lt;id, Item&gt;,另一个瞬态映射multimap&lt;id, id&gt; 描述哪个项目包含哪些其他项目。

【讨论】:

  • 感谢您的回答。事实上,这张地图是建立联系的中间步骤,我将不得不改变设计。
猜你喜欢
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
相关资源
最近更新 更多