【问题标题】:map/set iterators incompatible [c++] [closed]映射/设置迭代器不兼容 [c++] [关闭]
【发布时间】:2015-07-09 21:17:35
【问题描述】:

我正在尝试遍历地图,如下所示:

data = &server->update();

    for (auto const iter : *data)
    {
        do things
    }

但一旦 for 行运行,我就会收到一条错误消息,指出“映射/设置迭代器不兼容”。

数据变量是一个

std::map<unsigned int, Packet> *data;

它是一个指针,因为它位于:

public ref class ServerForm : public System::Windows::Forms::Form

这似乎不像任何不是指针的东西。

我尝试了多种方法来遍历此地图,但每次尝试都完全失败。非常感谢您了解为什么会发生这种情况以及如何解决它,谢谢。

【问题讨论】:

  • 更新函数的签名是什么?
  • 还有:你能用那张地图做其他事情吗,比如查询它的大小?
  • std::map&lt;unsigned int, Packet&gt; Server::update() 是更新函数@Daniel 的签名。我可以查询大小,但它是 0,就像在我的项目中一样,服务器启动,然后客户端加入迭代。一旦我启动服务器,项目就会崩溃并出现此错误。
  • 这真的是 C++ 吗? C++ 在类声明中没有 ref 关键字。

标签: c++ dictionary iterator std


【解决方案1】:
data = &server->update();
// same as
data = &(server->update());

由于 update 函数按值返回,因此您将指针绑定到具有自动存储持续时间的实例,其生命周期以该行结束(“临时”)。

事实上,在你的循环后面

for(auto const it : *data)

您正在取消引用无效指针,这会产生未定义的行为。

真正让我吃惊的是,代码竟然还在编译。我无法让这样的测试用例在 ideone/GCC 中工作。


要使用更新函数返回的临时值,您有以下可能性:

  1. 将地图存储在局部变量中。
  2. 通过将临时对象绑定到引用来延长其生命周期:

    auto & map = server->update ();
    

    这在调用堆栈中“向上”不起作用,因此您无法返回该引用。

  3. 将循环带入限制临时生命周期的完整表达式:

    for (auto const it : server->update()) {
      // ....
    

【讨论】:

  • 所以我应该让更新方法由 ref 返回?
  • 如果地图在更新函数之后仍然有效(例如,如果它是该服务器实例的成员),那么返回 (const) 引用可能是处理此问题的正确方法。
  • 更新函数后返回的地图不再存活。
  • 我通过使用临时本地地图来存储更新函数的结果取得了一些进展。当我启动服务器时,这不再崩溃。但是,每次我尝试使用断点分析数据时,Visual Studio 都会崩溃?
  • 无法帮助您使用 Visual Studio,但使用局部变量应该可以正常工作。所以这可能与那个无关。
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 2011-07-31
  • 1970-01-01
相关资源
最近更新 更多