问题描述
为什么调用移动构造函数而不是复制构造函数?当我删除移动构造函数时,然后调用复制构造函数。
使用:-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 中,甚至不会创建该临时对象,这将避免使用移动构造函数(主要与复制/移动省略版本相同,只是复制/移动不必可访问)。>
如果您删除了移动构造函数,因为您提供了副本一,则不会生成移动一,并且只有复制构造函数可用,并用于代替移动构造函数。