为什么我需要在临时 dynamic_bitset 上调用 std::move?
Why do I need to call std::move on a temporary dynamic_bitset?
我在这里讲一个冗长的背景故事,因为除了直接回答之外,我还想知道我导致这种情况的推理是否正确。
我有一个接受 dynamic_bitset<>
参数的函数(来自 Boost.dynamic_bitset)。
说它看起来像这样。
void foo(boost::dynamic_bitset<> db) {
// do stuff
}
碰巧它只被临时调用,从构造函数构建,如foo(boost::dynamic_bitset<>{5}.set())
(调用所有位设置的 5 位位集)。
我的位集只有少量的位(少于 32)。所以一开始,我想 "I'll just pass it by value; the copy is smaller than a pointer." 但后来我想 "It's dynamic, so it must allocate space on the heap. I want to avoid unnecessary allocations and frees."
所以,我可以做到
void foo(const boost::dynamic_bitset<>& db);
但是引用是一个指针,dynamic_bitset(大概)有一个指向它的数据的指针,所以在 foo
中使用 db
会经历两个间接级别,这看起来很愚蠢。显然,最好的方法是将指向数据的指针复制到 foo
,而无需重新分配和复制堆上的数据。
"Aha!"我说。 "Surely this is what move semantics are for." 所以,我把签名改成
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(即将过期的临时值),不是吗?
dynamic_bitset& set();
set()
returns 一个左值。
一般来说,如果函数 returns 按值,或按右值引用:
dynamic_bitset set();
dynamic_bitset&& set();
那么表达式 set()
是一个右值(在第一种情况下是纯右值,在第二种情况下是亡值)。但是因为在实际代码中 set()
returns 是一个左值引用,表达式 set()
是一个左值。
category values http://downloads.sehe.nl/Whosebug/value-categories.svg
我在这里讲一个冗长的背景故事,因为除了直接回答之外,我还想知道我导致这种情况的推理是否正确。
我有一个接受 dynamic_bitset<>
参数的函数(来自 Boost.dynamic_bitset)。
说它看起来像这样。
void foo(boost::dynamic_bitset<> db) {
// do stuff
}
碰巧它只被临时调用,从构造函数构建,如foo(boost::dynamic_bitset<>{5}.set())
(调用所有位设置的 5 位位集)。
我的位集只有少量的位(少于 32)。所以一开始,我想 "I'll just pass it by value; the copy is smaller than a pointer." 但后来我想 "It's dynamic, so it must allocate space on the heap. I want to avoid unnecessary allocations and frees."
所以,我可以做到
void foo(const boost::dynamic_bitset<>& db);
但是引用是一个指针,dynamic_bitset(大概)有一个指向它的数据的指针,所以在 foo
中使用 db
会经历两个间接级别,这看起来很愚蠢。显然,最好的方法是将指向数据的指针复制到 foo
,而无需重新分配和复制堆上的数据。
"Aha!"我说。 "Surely this is what move semantics are for." 所以,我把签名改成
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(即将过期的临时值),不是吗?
dynamic_bitset& set();
set()
returns 一个左值。
一般来说,如果函数 returns 按值,或按右值引用:
dynamic_bitset set();
dynamic_bitset&& set();
那么表达式 set()
是一个右值(在第一种情况下是纯右值,在第二种情况下是亡值)。但是因为在实际代码中 set()
returns 是一个左值引用,表达式 set()
是一个左值。
category values http://downloads.sehe.nl/Whosebug/value-categories.svg