为什么我需要在临时的dynamic_bitset上调用std :: move?

时间:2016-04-22 21:59:12

标签: c++ move-semantics boost-dynamic-bitset xvalue

我在这里讲述了一个长篇大论的背景故事,因为除了直接回答之外,我还想知道导致这种情况的推理是否正确。

我有一个函数采用dynamic_bitset<>参数(来自Boost.dynamic_bitset)。 说它看起来像这样。

void foo(boost::dynamic_bitset<> db) {
    // do stuff
}

碰巧它只是用构造函数构建的临时函数调用,就像在foo(boost::dynamic_bitset<>{5}.set())中一样(用5位bitset调用所有位都设置)。

我的位集只有少量位(少于32位)。所以起初,我认为&#34;我只是按价值传递它;副本小于指针。&#34;但后来我想&#34;它是动态的,所以它必须在堆上分配空间。我想避免不必要的分配和释放。&#34;

所以,我可以成功

void foo(const boost::dynamic_bitset<>& db);

但是引用是一个指针,而dynamic_bitset(可能)有一个指向其数据的指针,因此在db中使用foo会经历两个间接级别,这看起来很愚蠢。显然,最好的方法是将指向数据的指针复制到foo,而无需在堆上重新分配和复制数据。

&#34;啊哈&#34!;我说。 &#34;当然这就是语义的用途。&#34;所以,我将签名更改为

void foo(boost::dynamic_bitset<>&& db);

但是,调用foo(boost::dynamic_bitset<>{5}.set())会产生编译错误cannot bind 'boost::dynamic_bitset<>' lvalue to 'boost::dynamic_bitset<>&&'。 我必须打电话 foo(std::move(boost::dynamic_bitset<>{5}.set())) 一切正常。

为什么我需要调用std :: move? 这似乎显然是一个xvalue(暂时即将到期),不是吗?

1 个答案:

答案 0 :(得分:5)

来自the boost docs

dynamic_bitset& set();

set()返回一个左值。

通常,如果函数按值返回,或通过右值引用返回:

dynamic_bitset   set();
dynamic_bitset&& set();

然后表达式set()是一个右值(在第一种情况下是一个prvalue,在第二种情况下是一个xvalue)。但是因为在实际代码set()中返回左值引用,表达式set()是左值。

category values http://downloads.sehe.nl/stackoverflow/value-categories.svg