我在这里讲述一个冗长的背景故事,因为除了直接回答之外,我想知道导致这种情况的推理是否正确。
我有一个带dynamic_bitset<>
参数的函数(来自Boost.dynamic_bitset)。说它看起来像这样。
void foo(boost::dynamic_bitset<> db) {
// do stuff
}
碰巧它只使用从构造函数构建的临时foo(boost::dynamic_bitset<>{5}.set())
对象调用,如(使用所有位设置的 5 位位集调用)。
我的位集只有少量位(少于 32 个)。所以一开始,我想“我只是按值传递它;副本比指针小。” 但后来我想“它是动态的,所以它必须在堆上分配空间。我想避免不必要的分配和释放。”
所以,我可以做到
void foo(const boost::dynamic_bitset<>& db);
但是一个引用是一个指针,而一个dynamic_bitset(大概)有一个指向它的数据的指针,所以使用db
withinfoo
会经历两层间接,这看起来很愚蠢。显然,最好的方法是将指向数据的指针复制到 中foo
,而无需重新分配和复制堆上的数据。
“啊哈!” 我说。“当然,这就是移动语义的用途。” 所以,我将签名更改为
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(一个临时的即将到期),不是吗?