如何将rvalue放入未使用它的路径中

时间:2015-07-07 15:09:51

标签: c++11 rvalue-reference rvalue

当一个函数接受一个它在一些分支中没有使用的右值引用时,它应该如何处理rvalue以保持其签名的语义正确性并且对于所有者的所有权保持一致数据。考虑以下示例代码:

#include <memory>
#include <list>
#include <iostream>

struct Packet {};

std::list<std::unique_ptr<Packet>> queue;

void EnQueue(bool condition, std::unique_ptr<Packet> &&pkt) {
    if (condition) queue.push_back(std::move(pkt));
    else /* How to consume the pkt? */;
}

int main()
{
    std::unique_ptr<Packet> upkt1(new Packet());
    std::unique_ptr<Packet> upkt2(new Packet());

    EnQueue(true, std::move(upkt1));
    EnQueue(false, std::move(upkt2));

    std::cout << "raw ptr1: " << upkt1.get() << std::endl;
    std::cout << "raw ptr2: " << upkt2.get() << std::endl;

    return 0;
}

Enqueue函数的签名表示它将获取传递给它的数据的所有权,但只有当它到达 if 路径时才会成立,而是如果它到达 else < / strong>路径函数有效地不使用rvalue并且所有权返回给调用者,这可以通过upkt2.get从函数返回后 NULL来说明。实际效果是EnQueue的行为与其签名不一致。

现在的问题是 - 这是否是可接受的行为,或者EnQueue函数是否应该更改为一致,如果是这样的话?

1 个答案:

答案 0 :(得分:0)

我看到了三种解决方法。

  1. 记录函数退出后,“pkt处于有效但未指定的状态。”这样,调用者之后就不能对该参数做任何假设;如果他们需要它无论如何都被清除,他们可以明确地做到。如果他们不这样做,他们就不会支付他们不会使用的任何内部清理费用。

  2. 如果您希望在接受所有权时100%明确签名,只需按值pkt而不是右值参考(在评论中由@Quentin建议)。

  3. pkt

    构建临时
    if (condition) queue.push_back(std::move(pkt));
    else auto sink(std::move(pkt));