我在这里讲述了一个长篇大论的背景故事,因为除了直接回答之外,我还想知道导致这种情况的推理是否正确。
我有一个函数采用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(暂时即将到期),不是吗?
答案 0 :(得分:5)
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