Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';这是在没有开销的情况下实现push_back的最佳方法_C++_Performance_Circular List - Fatal编程技术网

C++ 什么';这是在没有开销的情况下实现push_back的最佳方法

C++ 什么';这是在没有开销的情况下实现push_back的最佳方法,c++,performance,circular-list,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

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

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;
}
struct节点{
T数据;
节点*next,*prev;
};    
//将数据推到列表的后面。
模板T和循环队列::推回(常量T和新数据)
{
Node*new_Node=新节点();
新建节点->数据=标准::移动(新建数据);
链路单元节点(新单元节点、单元头);
返回新节点->数据;
}
我目前的方法的问题是有太多的开销(因为我来自C语言,这些事情困扰着我)。例如,我将从MyClass添加一个对象:

CircularQueue<MyClass> list;
list.push_back(MyClass(arg1, arg2));
循环队列列表;
list.push_back(MyClass(arg1,arg2));
第一个问题是MyClass需要有一个没有参数的构造函数才能在
Node*new_Node=new Node()中使用因为创建节点结构将调用其中的对象(MyClass)的构造函数。我试过使用std::vector,但它不需要这个


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

您可以将节点放回原位

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
}
模板
类循环队列{
模板
后置(U&&…U)
{
Node*new_Node=new Node{{{std::forward(u)…}};//数据;
}
};
void foo(){
循环队列x;
//不要创建数据,传递需要创建的参数
x、 后置(10,20);
//如果确实需要,当然可以复制或移动现有数据
数据y(20,30);
x、 向后放置(y);//复制y
x、 向后放置(标准::移动(y));//移动y
}

const T&new\u data
只会将其转换为副本。不会有任何行动,不会的。不能从
const
对象中移动。这就是为什么右值引用永远不会
const
No它不会。const完全否定了移动语义。我看到的第一个也是最大的问题是为每个元素分配内存push@t.niese我认为这很有帮助,我的意思是不用创建对象然后使用移动赋值,我们可以直接使用移动构造函数。我认为这是最好的解决方案,尽管您发布的编译器资源管理器链接中的代码已被优化。
新节点{{{std::forward(u)…}
将以不可预测的方式与类一起运行,如
std::vector
。它需要替换为
新节点{T(std::forward(u)…)}