为什么使用移动构造函数而不是复制?

问题描述

为什么调用移动构造函数而不是复制构造函数?当我删除移动构造函数时,然后调用复制构造函数

使用:-fno-elide-constructors 来避免复制省略

#include <iostream>
class test
{
public:
    int x;
    char y;
    bool t;
    test()
    {
        std::cout << " constructed" << std::endl;
    }
    test(test &&temp)
    {
        std::cout << "move constructor" << std::endl;
    }
    test(const test &temp)
    {
        std::cout << "copy constructor" << std::endl;
    }
    template <typename... Args>
    static test create(Args... x)
    {
        test b(x...);
        return b;
    }
};
int main()
{
    test z = test::create();
    test v = test();
}

输出

 constructed
move constructor
move constructor
 constructed
move constructor

上述原因可能是什么?

解决方法

我认为这是基本的移动语义。将临时变量分配给非临时变量时,只要存在移动运算符(默认或使用指定),就会使用它。看看克劳斯·伊格尔伯格 (Klaus Igelberger) 的演讲。我认为是 cppcon 2019。 -道歉。我是想回复不回复

,

来自 https://en.cppreference.com/w/cpp/language/return#Automatic_move_from_local_variables_and_parameters,这主要是 NRVO 的后备:

然后重载决议选择构造函数用于初始化返回值[..]被执行两次:

  • 首先好像表达式是一个右值表达式(因此它可以选择移动构造函数),并且 如果第一个重载决议失败或

[...]

所以 return b; 当复制/移动没有被省略时会做一个移动构造函数(如果可用)。

对于 test v = test();test() 是一个右值,在 C++17 之前,将使用移动构造函数(如果没有省略)(如果可用)。

在 C++17 中,甚至不会创建该临时对象,这将避免使用移动构造函数(主要与复制/移动省略版本相同,只是复制/移动不必可访问)。>

如果您删除了移动构造函数,因为您提供了副本一,则不会生成移动一,并且只有复制构造函数可用,并用于代替移动构造函数。