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

标签 c++ performance circular-list

我正在尝试实现一个队列,您可以向它传递一个要添加到队列中的对象。

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

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

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

第一个问题是MyClass需要有一个不带参数的构造函数才能在Node* new_node = new Node();中使用因为创建 Node 结构将调用其中对象 MyClass 的构造函数。我尝试使用 std::vector 但它不需要这个。

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

最佳答案

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

关于c++ - 在没有开销的情况下实现push_back的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62891515/

相关文章:

c++ - 来自 int 数字的十六进制 *char

c++ - 成员函数指针权限

c++ - 侵入式、循环式、无分支式、双向链表——如何让链表识别节点成员字段?

c - 减少C中链表遍历时的迭代次数

java - 需要有关 Java 循环链表的帮助!

java - 查找遍历图中所有顶点的路线的更好算法是什么?

c# - 访问修饰符会影响性能吗?

c# - 为什么字典比列表快这么多?

mysql - 如何提高具有不依赖子查询的 MySQL 查询的性能?

c++ - “无效使用 void 表达式”传递函数参数