【发布时间】:2019-07-22 14:17:57
【问题描述】:
struct Bar
{
Bar(std::string&& val)
: m_Val(std::move(val)) {} // A
Bar& operator=(Bar&& _other) { m_Val = std::move(_other.m_Val); }
std::string m_Val;
}
struct Foo
{
void Func1(Bar&& param)
{
Func2(std::move(param)) // B
}
void Func2(Bar&& param)
{
m_Bar = std::move(param); // C
}
Bar m_Bar;
};
void main()
{
Foo f;
std::string s = "some str";
Bar b(std::move(s));
f.Func1(std::move(b));
}
假设您在main() 中调用move 来调用右值引用方法,是否有必要在A、B 和C 行中重复对move() 的额外调用?你已经有了右值引用,那么它在那些有 vs 没有的行中有什么不同吗?
我在 Bar 的 operator= 中了解到这是必要的,因为您在技术上是在移动 m_Val 而不是 _other 本身是否正确?
注意:最初,我错误地将右值引用称为右值参数。我很抱歉。我已经更正了这一点,以使问题更容易找到并更清楚。
【问题讨论】:
-
我知道您这样做可能是为了说明您的观点,但请注意,在您当前的示例中,您根本不需要编写
Bar的移动构造函数。 -
没有“右值参数”之类的东西。 named 引用生成一个 lvalue 表达式(是的,即使是右值引用也是左值)。因此,为了再次将其变为 xvalue,您需要再次应用
std::move。 -
@AnT 我仍然对你的头像应该是什么感到困惑。
-
@SombreroChicken - 为什么?如果我在main中制作字符串,我不需要移动它吗?整个事情,包括字符串都是人为的,但我的理解是,如果我想避免复制它,我需要移动它。
-
@user99999991 SombreroChicken 意味着对于这个
struct,在您的示例编译器中将隐式生成正确的移动 ctor 和移动赋值运算符,因此无需在此处手动定义它们。