当调用move构造函数时感到困惑

Confused when move constructor is called?

本文关键字:调用 move 构造函数      更新时间:2023-10-16

我一直在努力解决这个问题一段时间,我找不到一个解释。假设我有以下代码

class foo
{
public:
    foo()
    {std::cout << "Regular constructor n";}
    foo( const foo& a)                            //In abscence of const keyword the copy constructor is called
    {std::cout << "Copy constructor n";}
    foo& operator=(const foo& a) 
    {std::cout << "Copy Assignment operator n";}
    foo(foo&& a)
    {
        std::cout << "Move constructor n";
    }
    foo& operator=(foo&& a) 
    {std::cout << "Move Assignment operator n";}
    int a;
};

foo myfunction()
{
    foo d;
    d.a =120;
    return d;
}

现在如果我这样做

foo a = myfunction();

这是我所期望的。Myfunction()返回一个对象左值,但是由于Myfunction()是临时的,它将返回一个右值。我说的对吗?在这种情况下,move构造函数会被调用,这是有意义的。但是,如果我从复制构造函数中删除const关键字,则调用复制构造函数而不是移动构造函数。谁能给我解释一下为什么会这样?

VS2012有一个讨厌的扩展,允许临时绑定到左值引用。我们不能用现代的、符合标准的编译器来复制,这些编译器实际上省略了对copy/move构造函数的调用(因为RVO)。应用fno-elide-constructors选项显示,即使没有const,它们也确实调用了move-构造函数。

From cppreference

move构造函数在对象从相同类型的xvalue初始化时调用,它包括:

  • 初始化,T a = std::move(b);或者T a(std::move(b));,其中b的类型为T

  • 函数参数传递:f(std::move(a));,其中a为类型T, f为void f(T T)

  • 函数返回:返回a;在函数内部,比如T f(),其中a是T类型的,并且有一个move构造函数。