Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么使用移动构造函数而不是复制?_C++_Move_Copy Constructor_Move Semantics_Copy Elision - Fatal编程技术网

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

C++ 为什么使用移动构造函数而不是复制?,c++,move,copy-constructor,move-semantics,copy-elision,C++,Move,Copy Constructor,Move Semantics,Copy Elision,为什么调用移动构造函数而不是复制构造函数?当我移除move构造函数时,就会调用copy构造函数 用法:-fno省略构造函数以避免复制省略 #include <iostream> class test { public: int x; char y; bool t; test() { std::cout << " constructed" << std::endl; }

为什么调用移动构造函数而不是复制构造函数?当我移除move构造函数时,就会调用copy构造函数

用法:-fno省略构造函数以避免复制省略

#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();
}

上面的原因是什么?

我认为这是基本的移动语义。将临时变量指定给非临时变量时,只要存在移动操作符(默认或指定使用),就会使用它。看看克劳斯·伊格伯格的演讲。我想是2019年的cppcon。 -抱歉。我的意思是不回答,这主要是NRVO的退路:

然后执行两次重载解析,以选择用于初始化返回值[…]的构造函数:

  • 首先,将表达式视为右值表达式(因此它可以选择移动构造函数),然后 如果第一次重载解析失败或
[……]

so
返回b当不省略复制/移动时,将执行移动构造函数(如果可用)

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

在C++17中,甚至不会创建该临时对象,这将避免使用move构造函数(大多数情况下与copy/move省略版本相同,只是copy/move不必可访问)


如果删除移动构造函数,在提供复制构造函数时,不会生成移动构造函数,并且只有复制构造函数可用,并用于代替移动构造函数。

为什么这会让您感到惊讶?当assignedIt感兴趣时,会自动移动临时值。你在用什么编译器?我本来希望复制省略能够工作,因此唯一的输出应该是“构造的”。我尝试了它:gcc和clangprint only
构造的
,即使是几年前的版本。你会期望什么行为?您希望在哪里调用复制构造函数?为什么?对我来说,这里唯一有趣的是,你问题的标题不是“为什么使用移动构造函数而不是省略?”。@MariusBancila我明确使用了“-fno-elide构造函数”
 constructed
move constructor
move constructor
 constructed
move constructor