【发布时间】:2016-04-22 21:59:12
【问题描述】:
我在这里讲述的是一个冗长的背景故事,因为除了直接回答之外,我还想知道导致这种情况的推理是否正确。
我有一个函数采用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(大概)有一个指向它的数据的指针,所以在foo 中使用db 会经历两层间接,这看起来很愚蠢。显然最好的方法是将指向数据的指针复制到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(一个即将到期的临时值),不是吗?
【问题讨论】:
-
这不取决于
set是什么吗?
标签: c++ move-semantics boost-dynamic-bitset xvalue