我一直在关注this answer与What are the rules for automatic generation of move operations?的相关问题,并希望答案现在已经确定。
基于类中已声明的内容,该幻灯片显示哪些构造函数/赋值运算符为“未声明”,“默认”或“已删除”:
那是从这些slides中摘录的,红色方框表示此行为已被弃用。
编译以下内容时:
#include <iostream>
struct X
{
template<typename...T>
X(T&&...) {
std::cout << "Yay!\n";
}
~X() {}
};
int main() {
X x0;
X x1{x0};
X x2{std::move(x0)};
}
由于它们已编译且输出为“是!”,因此似乎未声明它们。三遍(至少对我来说这是件好事)。但是我想确认我可以依靠这种行为。
Frank指出,如果还添加了副本构造函数,它仍会显示“是!”。三遍,这是有趣的行为。做进一步的测试,如果添加了move构造函数,它只会说“是!”。两次。谁能解释这种行为?
答案 0 :(得分:2)
根据N4659(几乎为C ++ 17标准),它们仍被定义为默认值,但行为(仍)已弃用。
如果类定义未显式声明一个副本构造函数,则将隐式声明一个非显式的构造函数。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的copy构造函数将定义为delete;否则,被定义为默认值。如果该类具有用户声明的副本分配运算符或用户声明的析构函数,则后一种情况已弃用。
如果类定义未显式声明一个拷贝赋值运算符,则隐式声明一个。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的副本赋值运算符将定义为Delete;否则,被定义为默认值。如果该类具有用户声明的副本构造函数或用户声明的析构函数,则后一种情况已弃用。