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

Nic*_*teo 4 c++ move-semantics xvalue boost-dynamic-bitset

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

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

void foo(boost::dynamic_bitset<> db) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

碰巧它只是用构造函数构建的临时函数foo(boost::dynamic_bitset<>{5}.set())调用,如同(用5位bitset调用所有位设置).

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

所以,我可以做到

void foo(const boost::dynamic_bitset<>& db);
Run Code Online (Sandbox Code Playgroud)

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

"啊哈!" 我说."当然这就是语义学的用途." 所以,我将签名更改为

void foo(boost::dynamic_bitset<>&& db);
Run Code Online (Sandbox Code Playgroud)

但是,调用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(临时即将到期),不是吗?

How*_*ant 5

来自boost文档:

dynamic_bitset& set();
Run Code Online (Sandbox Code Playgroud)

set() 返回一个左值.

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

dynamic_bitset   set();
dynamic_bitset&& set();
Run Code Online (Sandbox Code Playgroud)

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

类别值http://downloads.sehe.nl/stackoverflow/value-categories.svg