简体   繁体   English

将 std::vector 传递给构造函数而无需复制

[英]Pass std::vector to constructor without copy

After a 2 years break, I've started using C++ again, and I'm pretty rusty.休息了 2 年之后,我又开始使用 C++,而且我已经很生疏了。 I'm trying to implement a 5-coloring algorithm for a graph, but I'm having trouble with vectors.我正在尝试为图形实现 5 着色算法,但我在使用向量时遇到了问题。

I've 3 classes (snippets below).我有 3 个课程(下面的片段)。 The problem is that somewhere in Graph::Graph(), a copy constructor is called on both vectors (While troubleshooting the Graph::solve() function, I found that the vertices in Edge::_from/Edge::_to are not references to the vertices inside Graph::_vertices, when I change the color of one vertex inside Graph::_vertices, vertices inside Edge::_to/Edge::_from aren't affected).问题是在 Graph::Graph() 的某个地方,两个向量都调用了一个复制构造函数(在对 Graph::solve() 函数进行故障排除时,我发现 Edge::_from/Edge::_to 中的顶点不是Graph::_vertices 中顶点的引用,当我更改 Graph::_vertices 中一个顶点的颜色时,Edge::_to/Edge::_from 中的顶点不受影响)。

I've used this code to test我用这段代码来测试

    Vertex v1 = Vertex("A");
    Vertex v2 = Vertex("B");
    std::vector<Vertex> vertices = { v1, v2 };

    v1.color() = 1;

    Edge e1_2 = Edge(v1, v2);
    std::vector<Edge> edges;

    std::cout << v1 << std::endl; //output A(1)
    std::cout << e1_2 << std::endl; //output A(1) -> B(-1) so v1 is a reference

    Graph g = Graph(edges, vertices);

    std::cout << v1 << std::endl; //output A(1)
    std::cout << e1_2 << std::endl; //output A(1) -> B(-1)
    std::cout << g.vertices().at(0) << std::endl; //output A(-1) WHY is it -1 and not 1 ?

    v1.color() = 2;
    std::cout << v1 << std::endl; //output A(2)
    std::cout << e1_2 << std::endl; //output A(2) -> B(-1)
    std::cout << g.vertices().at(0) << std::endl; //output A(-1)

I know it is the initilization list inside Graph::Graph() that call the copy constructor on both vectors, but I can't get rid of it because it won't compile without it, as the vectors must be initialized.我知道是 Graph::Graph() 中的初始化列表在两个向量上调用复制构造函数,但我无法摆脱它,因为没有它它不会编译,因为必须初始化向量。 But I don't get why Vertex::_identifier are copied, but Vertex::_color are set to the default value.但我不明白为什么 Vertex::_identifier 被复制,但 Vertex::_color 被设置为默认值。

I also used an initilization list in Edge::Edge(), but it didn't call the copy constructor on the vertices, as they are real references.我还在 Edge::Edge() 中使用了初始化列表,但它没有调用顶点上的复制构造函数,因为它们是真正的引用。

Is there a ""clean"" way to resolve this (without pointers if possible) ?有没有“干净”的方法来解决这个问题(如果可能,没有指针)?

Vertex顶点

class Vertex {
    private:
        std::string _identifier;
        int _color; //-1 = no color
    public:
        explicit Vertex(std::string identifier) : _identifier(identifier), _color(-1) {}
    ...
}

Edge边缘

class Edge {

    private:
        Vertex& _from;
        Vertex& _to;

    public:
        Edge(Vertex& from, Vertex& to) : _from(from), _to(to) {}

        Vertex from() const;
        Vertex to() const;
    ...
}

Graph图形

class Graph {
    private:

        std::vector<Vertex> _vertices;
        std::vector<Edge> _edges;
    public:
        Graph(std::vector<Edge>& edges, std::vector<Vertex>& vertices) : _edges(edges), _vertices(vertices) {}
    ...
}

Pass std::vector to constructor without copy将 std::vector 传递给构造函数而无需复制

Move instead of copy:移动而不是复制:

Graph(std::vector<Edge> edges, std::vector<Vertex> vertices)
    : _edges(std::move(edges)), _vertices(std::move(vertices))

// example usage
Graph g(std::move(edges), std::move(vertices));

However, avoiding copying of the vector is not sufficient for you.但是,避免复制向量对您来说是不够的。 You also copy vertices into the vector itself.您还可以将顶点复制到向量本身中。 You could instead create the edges between the copies in the vector rather than the variables they were copied from:您可以改为在向量中的副本之间创建边,而不是创建它们从中复制的变量:

Edge e1_2 = Edge(vertices[0], vertices[1]);

Furthermore: Don't use reference members.此外:不要使用引用成员。 Use pointers or reference wrappers.使用指针或引用包装器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有复制构造函数的情况下创建 class 的 std::vector 的 std::vector - Create a std::vector of std::vectors of class without copy constructor 在没有复制构造函数的情况下实例化std :: vector的唯一元素 - instantiating unique elements of std::vector without a copy constructor 如何在std :: vector中存储没有复制或移动构造函数的对象? - How to store objects without copy or move constructor in std::vector? 有没有可能传递std :: vector <int> 作为获取std :: vector的乐趣的参数 <std::array<int, 3> &gt;? - Is it possible without copy to pass std::vector<int> as param to fun that get std::vector<std::array<int, 3>>? std::vector 初始化元素的移动/复制构造函数 - std::vector initialization move/copy constructor of the element std::vector 是否有引用的复制构造函数? - Does std::vector have a copy constructor for references? 返回std :: vector时未调用复制构造函数 - copy constructor not called when returning a std::vector 为什么在此示例中使用 std::vector 调用复制构造函数? - Why is the copy constructor called in this example with std::vector? 为什么std :: vector :: emplace在没有调用任何拷贝构造函数的情况下调用析构函数? - Why does std::vector::emplace call destructor without any copy constructor called? std::thread 通过引用调用复制构造函数 - std::thread pass by reference calls copy constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM