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

时间:2020-07-14 08:58:28

标签: c++ performance circular-list

我正在尝试实现一个队列,在该队列中将要添加到队列中的对象传递给该队列。

referring_site

我当前方法的问题是开销太大(因为我来自C,所以这些事情困扰了我)。例如图像,我将从MyClass添加一个对象:

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;
}

第一个问题是MyClass需要有一个没有参数的构造函数才能在CircularQueue<MyClass> list; list.push_back(MyClass(arg1, arg2)); 中使用,因为创建Node结构将调用其中的对象的构造函数MyClass。我尝试了std :: vector,但并不需要这个。

第二个问题是开销太大,Node* new_node = new Node();将在堆栈中创建一个右值对象,然后发送到list.push_back(MyClass(arg1, arg2));,然后在堆中创建一个新对象(不带参数列表),然后移动使用移动分配将其所有成员添加到新对象,是否有更快的解决方案?

1 个答案:

答案 0 :(得分:2)

您可以emplace_back您的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

相关问题