【问题标题】:Why can't I insert objects into a map in c++为什么我不能在 C++ 中将对象插入到地图中
【发布时间】:2019-09-11 10:04:03
【问题描述】:

所以我有一个函数应该返回以下地图:
map<MyObj*, Datastruct>

尝试从包含所述对象的列表中插入对象时:

for(auto element: myList){  
    Datastruct str;  
    str.property1 = element.property1;  
    str.property2 = element.property2;  
    saidMap.insert(element.PointerToMyObj, str);  
}

myList 中的对象包含指向 myObj 的指针和一些我需要从列表移动到地图的属性。在下面的函数中执行了这段代码:

map<MyObj*, Datastruct> listToMap = convertList(myList);

编译器对我大吼大叫:

"没有匹配的函数调用'std::map::insert(MyObj*&, Datastruct&)"

在这里我很无助。我不知道如果 myList(见上文)中的 element 包含

,编译器为什么会显示我正在尝试传递对函数的引用

MyObj *PointerToMyObj;

在我看来,哪个是传递给插入函数的正确类型,对吗? 我也尝试过

std::make_pair

因此编译器对我大喊大叫,因为我试图将一对插入到 a
map<MyObj*, Datastruct>.

我完全迷路了。有人可以向我解释我做错了什么吗?

【问题讨论】:

  • 抱歉,这个问题中的代码格式不正确,StackOverflow 不允许我发布它对我大喊“缩进 4 个空格或按 ctrl+k”,但我试图无济于事。我猜这不是我的日子。
  • 您从 IDE 复制代码文本,选择它并按 ctrl+k 或使用 {} 按钮。如果仍然无法正确格式化,请使用网站:format.krzaq.cc 重新格式化,然后粘贴并选择它并按 ctrl+k 或使用 {} 按钮
  • 配对尝试的错误是什么?你检查过the reference而不是猜测吗?
  • 错误是:“没有匹配函数调用 std::map::insert(std::pair
  • 提示:不要惊慌,而是 rtfm(阅读-the-fine-manual)。 Insert 确实对您传递的参数没有重载,尽管它还有其他参数:en.cppreference.com/w/cpp/container/map/insert

标签: c++ dictionary insert


【解决方案1】:

地图的值类型不是

std::pair<MyObj*, Datastruct>

但是

std::pair<MyObj* const, Datastruct>

大概你在某处硬编码了pair类型,但错过了const

或者,如果您写了saidMap.insert(std::make_pair(element.PointerToMyObj, str)),那么这应该可以工作,但您的代码中还有其他问题。


但使用emplace要容易得多:

saidMap.emplace(element.PointerToMyObj, str);  

insert 的这个 C++11 版本拥有“透明”工作所需的所有魔法机制。

【讨论】:

    【解决方案2】:

    您的代码几乎没问题。你得到这个编译器错误是因为map::insert 真的没有这样的重载。这是您在查看std::map 文档时错过的一个小细节。这样map::insert 就不能作为隐式构造函数工作,这就是您尝试在粘贴的代码中使用它的方式。 这是您可以通过放置 - map::emplace:

    来实现的
    for(auto element : myList){  
      Datastruct str;  
      str.property1 = element.property1;  
      str.property2 = element.property2;  
      saidMap.emplace(element.PointerToMyObj, str);
    }
    

    使用map::insert():insert函数用于在map中插入key-valuepair,有3个一般的重载,其实它们更多,但这些是如何在地图中插入背后的主要思想。

    • insert(pair):简单地在映射中插入一个新对,其中pair.first 是key,pair.second 是value。仅当键不在地图中时才会发生。
    • insert(it, pair):使用迭代器和对进行插入,其中it 是指向要插入对的位置的指针。
    • insert(begin, end):用于通过接受映射的beginend 的迭代器从另一个映射复制元素。

    在您的情况下,您错过了实际传递pair 的方法。您可以在插入参数列表中构造它,如下所示:

    for(auto element : myList){  
      Datastruct str;  
      str.property1 = element.property1;  
      str.property2 = element.property2;  
      saidMap.insert( /*implicitly derive a pair as:*/ { element.PointerToMyObj, str } );
    }
    

    注意:这是一个post-C++11 功能,因此请确保您将编译器的 C++ 版本设置为至少该版本。

    我已经在 Compiler Explorer (godbolt) 中使用 map::insert 的工作版本复制了您的代码,供您查看(在 gccclang 编译器中):@ 987654321@.

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-22
      相关资源
      最近更新 更多