Search code examples
c++performancecircular-list

what's the optimum way to implement push_back without overhead


I'm trying to implement a Queue where you pass to it an Object to be added to the Queue.

struct Node {
    T data;
    Node *next, *prev;
};    
// Push data to the back of the list.
template <class T> T& CircularQueue<T>::push_back(const T&& new_data)
{
    Node* new_node = new Node();
    new_node->data = std::move(new_data);
    link_node(new_node, m_head);
    return new_node->data;
}

The problem with my current approach is there is too much overhead (as i come from C these things bothers me). for example image i will add an object from MyClass:

CircularQueue<MyClass> list;
list.push_back(MyClass(arg1, arg2));

The first problem is that the MyClass needs to have a constructor without argument to be used in Node* new_node = new Node(); since creating a Node structure will call the constructor of the object inside it which is MyClass. i tried with std::vector and it didn't require this.

The second problem is too much overhead, list.push_back(MyClass(arg1, arg2)); will create an rvalue object in the stack then send to push_back, it then creates a new object (with no argument list) in the heap then move all of its members to the new object using move assignment, is there any faster solution ?


Solution

  • you can emplace_back your Node

    template <class T> 
    class CircularQueue {
        template<typename... U>
        T &emplace_back(U&&... u)
        {
           Node *new_node = new Node{{std::forward<U>(u)...}}; // <data is created here
            // link_node(new_node, m_head);
           return new_node->data;
        }
    };
    void foo() {
        CircularQueue<Data> x;
        // Do not create a Data, pass the parameters you need to create
        x.emplace_back(10, 20);
        // If you actually need to, you can of course copy or move an existing Data
        Data y(20, 30);
        x.emplace_back(y); // copies y
        x.emplace_back(std::move(y)); // moves y
    }
    

    https://godbolt.org/z/z68q77