【问题标题】:Passing around reference of structure is invalidated传递结构的引用无效
【发布时间】:2022-01-13 10:38:20
【问题描述】:

我不确定是什么导致了错误。我在以下代码中创建了一个可行的替代品,它复制了我面临的问题。代码一目了然。

这是结构声明

#include <iostream>
#include <unordered_map>
#include <memory>
#include <vector>

using namespace std;

struct Point
{
    Point(float _x, float _y, float _z)
        : x(_x), y(_y), z(_z) {}
    float x;
    float y;
    float z;
};

struct Polyline
{
    std::vector<Point> points;
};

struct Geometry
{
    std::string id;
    std::unique_ptr<Polyline> polyline;
};

一些实用功能

void printPolyline(const Polyline& polyline)
{
    size_t idx = 0;
    for (const auto& p : polyline.points)
    {
        cout << "point idx = " << idx << "\t point: "
             << p.x << ", " << p.y << ", " << p.z << endl;
        ++idx;
    }
}

void printGeometryDetails(const Geometry& geometry)
{
    cout << "id = " << geometry.id << endl;
    if (geometry.polyline == nullptr)
    {
        cout << "Polyline is null" << endl;
        return;
    }
    printPolyline(*geometry.polyline);
}

以下是我尝试运行的方式。

int main()
{
    std::unordered_map<std::string, const Geometry&> map;

    std::unique_ptr<Polyline> geometry = std::make_unique<Polyline>();
    geometry->points.emplace_back(0, 0, 0);
    geometry->points.emplace_back(1, 0, 0);
    geometry->points.emplace_back(2, 0, 0);

    map.insert({"geometry-id-1", {"id1", std::move(geometry)}});
    printGeometryDetails(map.find("geometry-id-1")->second);
}

我希望打印多段线,但它显示“多段线为空”(即条件 if (geometry.polyline == nullptr)printGeometryDetails 函数中被评估为 true)。我真的不确定我在这里犯了什么错误导致了这种行为。

如果有人能指出我所犯的错误,我将不胜感激。

系统详情:Linux Ubuntu 20.04,编译器详情:

g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

  • 您不能将const Geometry&amp; 作为映射中的映射类型。这就是std::reference_wrapper 的用途
  • 为什么首先要参考?为什么不std::unordered_map&lt;std::string, Geometry&gt; map;
  • 我试图复制一个更大的问题。事情是Geometry 删除了复制构造函数。这就是我想在地图中保留参考的主要原因。
  • 参考只是参考。谁保留了实物?
  • 使用emplace时无需复制

标签: c++ unique-ptr unordered-map


【解决方案1】:

问题是为插入地图而创建的Geometry 对象的生命周期,即这一行:

    map.insert({"geometry-id-1", {"id1", std::move(geometry)}});

地图只存储对对象的引用,但对象本身不在此行之后。

将其替换为以下内容应该可以使其按预期工作:

    Geometry g = {"id1", std::move(geometry)};
    map.insert({"geometry-id-1", g});

【讨论】:

    猜你喜欢
    • 2013-06-04
    • 2013-05-12
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 2014-12-13
    相关资源
    最近更新 更多