简体   繁体   English

在没有开销的情况下实现 push_back 的最佳方法是什么

[英]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.我正在尝试实现一个队列,您将在其中将 Object 添加到队列中。

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).我目前的方法的问题是开销太大(因为我来自 C,这些事情让我很困扰)。 for example image i will add an object from MyClass:例如,我将从 MyClass 添加一个 object:

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();第一个问题是 MyClass 需要有一个没有参数的构造函数才能在Node* new_node = new Node();中使用。 since creating a Node structure will call the constructor of the object inside it which is MyClass.因为创建 Node 结构会调用其中的 object 的构造函数,即 MyClass。 i tried with std::vector and it didn't require this.我尝试使用 std::vector ,它不需要这个。

The second problem is too much overhead, list.push_back(MyClass(arg1, arg2));第二个问题是开销太大, 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?将在堆栈中创建一个右值 object 然后发送到push_back ,然后在堆中创建一个新的 object (没有参数列表)然后将其所有成员移动到新的 ZA8CFDE6331BD59EB2AC96F8911C4B66

you can emplace_back your Node你可以 emplace_back 你的节点

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 https://godbolt.org/z/z68q77

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM