考虑以下代码:
#include <iostream>
struct S
{
S() {std::cout << "default ctorn";}
S(const S&) {std::cout << "copy ctorn";}
S(S &&) {std::cout << "move ctorn";}
};
int main() {
S base;
S &&ref = (S&&)base;
S obj(ref);
return 0;
}
令人惊讶的是,S obj(ref);
调用了复制ctor而不是移动ctor
但是,如果我用S obj((S&&)ref);
替换这一行,那么move-ctor将按预期调用。
为什么会发生这种情况?为什么我需要强制转换来调用move构造函数?
作为一个表达式, 使用ref
是左值,任何命名任何类型变量的表达式也是如此。因此,它将绑定到左值引用(对于复制构造函数),而不是右值std::move
(或等效的强制转换表达式)会给出一个右值表达式,用于表示对象。这将绑定到右值引用,因此选择了move构造函数。