Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does queue create a copy?

Tags:

c++

stl

If I push an existing object into a queue:

struct Node {int x; int y;};
std::vector<Node> vec;
vec.push_back(Node(1, 3));

std::queue<Node> q;
q.push(vec[0]);

At the last line, does q store the address (pointer or reference, whatever except the object itself) of vec[0], or does it copy the whole Node object into q?

like image 525
Neo Avatar asked Jul 14 '20 07:07

Neo


2 Answers

It will get copied as you assign an rvalue reference. It will get moved if you assign an lvalue reference. (temporary object).

To check, use copy constructor / operator and move constructor / operator overloading:

#include <iostream>
#include <vector>
#include <queue>

struct Node {
    int x;
    int y;

    Node(int x, int y) : x(x), y(y)
    {
        std::cout << "constructor" << std::endl;
    }

    Node(Node const & original) : x(original.x), y(original.y)
    {
        std::cout << "copy constructor" << std::endl;
    }

    Node(Node const && original) : x(original.x), y(original.y)
    {
        std::cout << "move constructor" << std::endl;
    }

    Node & operator=(Node const & original) {
        std::cout << "assignment operator" << std::endl;
        if(this != &original) {
            x = original.x;
            y = original.y;
        }
        return *this;
    }

    Node & operator=(Node const && original) {
        std::cout << "move operator" << std::endl;
        if(this != &original) {
            x = original.x;
            y = original.y;
        }
        return *this;
    }
};


int main() {

    std::vector<Node> v;

    Node n(1,3);        // constructor
    Node m(3, 4);       // constructor

    m = n;              // assignment operator
    n = Node(2, 3);     // constructor + move operator

    v.push_back({1,2});     // constructor + move constructor
    v.push_back(n);         // copy constructor

    std::queue<Node> q;
    q.push(v[0]);           // copy constructor

    return 0;
}
like image 168
PirklW Avatar answered Nov 12 '22 18:11

PirklW


It does create a copy. In fact, you can always find out where a copy or move occurs by overwriting the copy or move constructors:

class Node 
{
public:
    Node(int x, int y) { std::cout << "Create node" << std::endl; }
    Node(const Node&) { std::cout << "Copy node" << std::endl; }
    Node(Node&&) { std::cout << "Move node" << std::endl; }
    virtual ~Node() = default;
};

For your program this prints

Create node
Move node
Copy node

Since

std::vector<Node> vec;
vec.push_back(Node(1, 3));  // Creates a temporary node and moves it into the vector.

std::queue<Node> q;
q.push(vec[0]);             // Copys the node.
like image 34
Carsten Avatar answered Nov 12 '22 16:11

Carsten