C++11 移动构造函数不被调用?(C+;+;11)

C++11 移动构造函数不被调用?(C+;+;11),c++11,move-constructor,C++11,Move Constructor,在下面的示例中,为什么在fun内部的“copy”构造中不调用move构造函数,即使“fun”的“src”参数是显式的右值引用,并且仅在该构造中使用 struct Toy { int data; Toy(): data(0) { log("Constructed"); } Toy(Toy const& src): data(src.data) { log("Copy-constructed"); }

在下面的示例中,为什么在fun内部的“copy”构造中不调用move构造函数,即使“fun”的“src”参数是显式的右值引用,并且仅在该构造中使用

struct Toy {
    int data;

    Toy(): data(0)
    {
        log("Constructed");
    }

    Toy(Toy const& src): data(src.data)
    {
        log("Copy-constructed");
    }

    Toy(Toy&& src): data(src.data)
    {
        log("Move-constructed");
    }
};

Toy fun(Toy&& src)
{
    Toy copy(src);
    copy.data = 777;
    return copy;
}

Toy toy(fun(Toy())); // LOG: Constructed Copy-constructed

虽然
Bob&&b
是一个右值引用,但所有在构造后命名使用的数据都将其用作左值

因此,
Bob&&b
将只绑定到右值,但当您使用它时,它将不移动

获取右值引用的唯一方法是:

  • 没有名称的值,例如临时返回值或强制转换的结果

  • 在简单的
    返回x中使用局部值变量语句

  • 显式强制转换为右值,例如使用
    std::move
    std::forward

这可以防止数据在一行上以静默方式移动,然后在下一行上使用。它有助于将rvalue理解为使用时“程序员说这个表达式之后不需要”,以及在函数参数中“只获取之后不需要的东西”。上面的临时/返回异常是编译器可以相对安全地保证这一点的两个点


最后,请注意,通用引用(
auto&&
T&&
)看起来像右值引用,但有时不是。

可能重复您的示例既不完整也不可用,下次发布其他人可以使用的内容时,我不明白复制省略或返回值优化与函数中“复制”对象的构造方式有什么关系。发生的事情显然是违反直觉和适得其反的。代码注释表明move构造函数从未被调用。这个问题提到了'src'参数是一个右值引用,用于在'fun'中构造'copy'对象,我认为这足以让这里的聪明人理解我预期的移动构造发生在哪里-_-我不太明白。。。传递给fun的Toy()是一个没有名称的值,fun将其识别为“以后不需要的东西”,事实上,除了构造另一个对象之外,它从未被使用过,因此编译器为什么不能执行移动?@user3026691在方法中它有一个名称-
src
,因此它是一个左值。它不是强制转换为右值,也不是在
返回x中使用的本地值,因此很明显,它在使用点是一个左值。编译器遵循C++11的规则,即“左值”。要修复,
std::move
。我不打算讨论为什么C++11在这种情况下说“左值”,因为它与您的问题无关。