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