【问题标题】:Should I implement rvalue push function and should I use std::move?我应该实现右值推送功能,我应该使用 std::move 吗?
【发布时间】:2020-02-21 11:40:43
【问题描述】:

作为练习,我正在用 C++11 实现一个堆栈类。
这是相关代码:

template <class T>
class stack
{
private:
    T * elements;
    std::size_t capacity;
    std::size_t count;

public:
    explicit stack(std::size_t capacity) : capacity(capacity)
    {
        elements = new T[capacity];
    };

    ~stack()
    {
        delete[] elements;
    };

    void push(const T & t)
    {
        if (capacity > count)
        {
            elements[count++] = t;
        }
    }

    void push(T && t)
    {
        if (capacity > count)
        {
            elements[count++] = std::move(t);
        }
    }
};

我使用的类如下:

stack<std::string> stack_test(2);
stack_test.push("string1");

std::string string2 = "string2";
stack_test.push(string2);

正如预期的那样,第一次推送使用push(T && t),而第二次推送使用push(const T & t)

我是否应该实现右值推送(即是否需要实现 push(T && t))?
我应该在其中使用 std::move() 吗?

【问题讨论】:

  • 你已经实现了右值和左值推送,rvalue push 是什么意思?
  • 我认为你已经很好地完成了这两个重载。
  • @ConstantinosGlynos 第一次推送会创建一个临时移动,该移动在void push(T &amp;&amp; t) 函数中分配。第二个推送副本分配在void push(const T &amp; t)。两者看起来都不错。
  • 我不确定如何解释这两个问题。 “我应该实现右值推送吗?” - 你已经做到了。 “我应该在其中使用 std::move() 吗?” - 是的,否则它会像第一次重载一样被复制分配。
  • 初始化计数=0;内部构造函数。我检查了你的代码,右值函数实现正确,在里面你可以在移动操作后检查 t 是否为空。

标签: c++ c++11 move-semantics rvalue-reference


【解决方案1】:

鉴于您将t 存储在两个pushes 中,您可以拥有一个

void push(T t)
{
    if (capacity > count)
    {
        elements[count++] = std::move(t);
    }
}

但实际上,您应该使用 std::vector&lt;T&gt; elements;(或 std::deque / std::list),就像 std::stack 所做的那样

【讨论】:

  • 如果您在push 中传递的是对需要保留在内存中的现有对象的引用,会发生什么?我认为你最终会得到同一个对象的两个单独的副本,一个可以在堆栈之外更新。我认为这不是一个好方法……
  • 我不明白。这样的实现不会移动 OP 示例中的 string2 吗?我不认为这是预期的行为......
  • @Fareanor no,调用stack_test.push(string2); 将从string2 复制构造参数t。它们是独立的对象
  • @ConstantinosGlynos 不,你会有一个副本和一个移动,因为t 是一个独立的对象
  • @HBv6 它没有更改 C++11 中的第一个重载,而是添加了第二个。它还保证“额外”移动不会发生,但它可能已被忽略。另请注意,std:: 的实现可能不完全具有这些重载,只要可观察到的行为是指定的
猜你喜欢
  • 1970-01-01
  • 2011-02-07
  • 2011-09-09
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 2013-02-06
  • 2015-06-04
  • 2013-08-06
相关资源
最近更新 更多