C++ 在 map 上循环 - 消失的对象

标签 c++ std

所以,我在我的代码中发现了一个我很难理解的相当奇怪的错误。我有一个 std::map ,我在其中存储了一些信息。当我第一次遍历它时,一切看起来都很好,但第二次,数据丢失了。

首先,我像这样使用结构和类:

struct Eng::Pixel{
        unsigned int x;
        unsigned int y;
    };

class Eng::Edge{
public:
enum EdgeType { INTER, INTRA};
EdgeType type;
}

class Eng::Cluster{
public:
std::map<Pixel, std::vector<Edge>> trans;
}

基本上,一个簇包含一个像素图。此图中的每个像素都包含称为边缘的过渡点。每个 Pixel 可以有不止一条边——一条边可以是 inter(0) 或 intra(1) 类型。请注意,一些 namespace 可能会丢失,因为我正在尝试尽可能简化我的问题。

当我遍历代码时:

std::vector<Cluster> resClusters = this->GenerateClusters();

for(Cluster cluster : resClusters) //For a given cluster in clusters
        {
            this->CreateIntraEdges(cluster); //Create our intra edges. Succeeds.
            std::cout << "Cluster: " << cluster << std::endl; //Prints the bounds of the cluster.
            std::cout << "Cluster has " << cluster.trans.size() << " transition pixels." << std::endl; //Prints the keys of the map jsut fine. 
            for (const auto& p : cluster.trans ) //For each member of the map
            {
                for(Edge ed : p.second) //For each edge from std::vector<Edge>
                {
                    std::cout << ed.type << " Start: " << ed.s << " End: "<< ed.e << std::endl;
                }
            }
        }

打印效果很好:

Cluster has 6 transition pixels.
0 Start: {2,14} End: {2,15}
1 Start: {2,14} End: {5,14}
1 Start: {2,14} End: {14,0}
1 Start: {2,14} End: {14,6}
1 Start: {2,14} End: {14,8}
1 Start: {2,14} End: {14,14}
0 Start: {5,14} End: {5,15}
...

然而,在没有 this->CreateIntraEdges 的情况下再次运行循环,我们得到:

Second run! 
Cluster: Min: {0,0} Max: {14,14}
Cluster has 6 transition pixels.
0 Start: {2,14} End: {2,15}
0 Start: {5,14} End: {5,15}
0 Start: {14,0} End: {15,0}
0 Start: {14,6} End: {15,6}
0 Start: {14,8} End: {15,8}
0 Start: {14,14} End: {15,14}
0 Start: {14,14} End: {14,15}
...

现在,如果您还想查看 CreateIntraEdge,请执行以下操作:

    void CreateIntraEdges(Cluster& c)
    {
        for (const auto& p1 : c.trans ) //For each object in the map.
        {
            for (const auto& p2 : c.trans ) //For each object in the map
            {
                if(p1.first == p2.first)
                {
                    continue;
                }
                auto [path, weight] = this->GetPath(c, p1.first, p2.first); //See if the two edges can connect.
                if(path.size() > 0)
                {
                    Edge newedge;
                    newedge.Set(p1.first, p2.first, weight, Edge::INTRA);
                    c.trans[p1.first].push_back(newedge); //Push it back onto the std::vector<Edge> for the pixel p1.first
                }
            }
        }
    }

为什么循环不再能看到类型为 1 的边?是汽车的原因吗?

由于 map 使用自定义结构,我还没有实现迭代器。这可能是问题的根源吗?

最佳答案

您创建了许多对象的拷贝...

std::vector<Cluster> resClusters = this->GenerateClusters();

这里 resCluster 是一个拷贝,对它的更改不会存储在 this 中(如果那里有 vector )。

同理

for(Cluster cluster : resClusters)

这里的 cluster 是 vector 中元素的拷贝。一旦循环迭代或结束,对 cluster 的更改将丢失。

您可能需要引用,至少对于循环:

for(Cluster& cluster : resClusters)

关于C++ 在 map 上循环 - 消失的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59139429/

相关文章:

c++ - N 的阶乘,其中 N 大于 200

c++ - 如何在C++中获取空格之前和空格之后的值

c++ - 为什么返回 vector<string> 会抛出 std::bad_alloc 异常?

PHP 对象 : property Object Vs stdClass Object - which one is better?

c++ - 是否有可能来自引用的段错误?

c++ - 在Qt中从父节点中查找子节点

c++ - 使用隐式转换模拟 C++ 函数模板实例化

java - JNI Java 使用将对象作为参数的 DLL 函数

c++ - 何时使用 std::invoke 而不是简单地调用可调用对象?

c++ - 使用更新的 C++ 标准向后移植的类型和模板扩展命名空间 std