以下移动构造函数代码是否安全? [英] Is the following move constructor code safe?
问题描述
这是 X
的移动构造函数:
X::X(X&& rhs)
: base1(std::move(rhs))
, base2(std::move(rhs))
, mbr1(std::move(rhs.mbr1))
, mbr2(std::move(rhs.mbr2))
{ }
这些是我很担心的事情:
These are the things I'm wary about:
- 我们从
rhs
两次和rhs
不能保证处于有效状态。是不是base2
? 的初始化的未定义的行为 - 我们正在移动
rhs
到mbr1
和mbr2
c $ c>已经从(并且不能保证处于有效状态)为什么要移动。
- We're moving from
rhs
twice andrhs
isn't guaranteed to be in a valid state. Isn't that undefined behavior for the initialization ofbase2
? - We're moving the corresponding members of
rhs
tombr1
andmbr2
but sincerhs
was already moved from (and again, it's not guaranteed to be in a valid state) why should this work?
这不是我的代码。我在网站上找到了。这个移动构造函数是否安全?
This isn't my code. I found it on a site. Is this move constructor safe? And if so, how?
推荐答案
这大约是隐式移动构造函数的工作原理:每个base和成员子对象都是move-从 rhs
的相应子对象构造。
This is approximately how an implicit move constructor typically works: each base and member subobject is move-constructed from the corresponding subobject of rhs
.
假设 base1
和 base2
是 X
的基础,没有构造函数 X
/ X&
/ X&&< / code> /
const X& code>,它是安全的书面。
std :: move(rhs)
将隐式转换为 base1&&
(分别 base2& ;&
)传递给基类初始化器。
Assuming that base1
and base2
are bases of X
that do not have constructors taking X
/ X&
/ X&&
/ const X&
, it's safe as written. std::move(rhs)
will implicitly convert to base1&&
(respectively base2&&
) when passed to the base class initializers.
编辑:这个假设实际上咬了我几次,当我有一个完全匹配 X&&
的基类中的模板构造函数。显式地执行转换会更安全(虽然令人难以置信的迂腐):
The assumption has actually bitten me a couple of times when I had a template constructor in a base class that exactly matched X&&
. It would be safer (albeit incredibly pedantic) to perform the conversions explicitly:
X::X(X&& rhs)
: base1(std::move(static_cast<base1&>(rhs)))
, base2(std::move(static_cast<base2&>(rhs)))
, mbr1(std::move(rhs.mbr1))
, mbr2(std::move(rhs.mbr2))
{}
甚至只是:
X::X(X&& rhs)
: base1(static_cast<base1&&>(rhs))
, base2(static_cast<base2&&>(rhs))
, mbr1(std::move(rhs.mbr1))
, mbr2(std::move(rhs.mbr2))
{}
我认为应该完全复制编译器隐式生成 X(X&&)= default;
没有其他基类或成员 base1
/ base2
/ mbr1
/ mbr2
。
which I believe should exactly replicate what the compiler would generate implicitly for X(X&&) = default;
if there are no other base classes or members than base1
/base2
/mbr1
/mbr2
.
编辑:C ++ 11§12.8/ 15描述了隐式成员方式复制/移动构造函数。
EDIT AGAIN: C++11 §12.8/15 describes the exact structure of the implicit member-wise copy/move constructors.
这篇关于以下移动构造函数代码是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!