Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++ 编译器在不应';T_C++_C++11_C++14_Move Semantics - Fatal编程技术网

C++ 编译器在不应';T

C++ 编译器在不应';T,c++,c++11,c++14,move-semantics,C++,C++11,C++14,Move Semantics,从N3337开始: 如果类X的定义没有显式声明移动 构造函数,则仅当且仅当 如果 X没有用户声明的复制构造函数,X没有 用户声明的复制分配运算符,X没有 用户声明的移动分配运算符,X没有 用户声明了析构函数,移动构造函数将不会 隐式定义为已删除 第一个问题是:为什么编译器不应该生成移动构造函数(有用户声明的析构函数和其他函数阻止移动构造函数的生成)。 下面的示例程序打印constructorCounter=5,这意味着使用了移动构造函数(没有移动操作值::constructorCounter应该

从N3337开始:

如果类X的定义没有显式声明移动 构造函数,则仅当且仅当 如果

X没有用户声明的复制构造函数,X没有 用户声明的复制分配运算符,X没有 用户声明的移动分配运算符,X没有 用户声明了析构函数,移动构造函数将不会 隐式定义为已删除

第一个问题是:为什么编译器不应该生成移动构造函数(有用户声明的析构函数和其他函数阻止移动构造函数的生成)。 下面的示例程序打印
constructorCounter=5
,这意味着使用了移动构造函数(没有移动操作值::constructorCounter应该是10)

#包括
阶级价值{
公众:
值(){
++构造计数器;
}
值(常量int值)
:_值(value)
{
++构造计数器;
}
值(常量值和其他)
:_值(其他._值)
{
++构造计数器;
}
常量值和运算符=(常量值和rhs){
_值=rhs.\u值;
返回_值;
}
~value(){}
静态整数构造函数计数器;
私人:
int_值;
};
int值::构造函数计数器=0;
类数组{
公众:
//数组()=删除;
//数组(数组&&)=删除;
数组(常量整数大小)
:_大小(大小),_值(新值[大小])
{
std::clog首先,行:

array c(array(5));
导致使用复制构造函数(因为没有用户声明的移动构造函数)。但是,由于它恰好是
c
对象构造,编译器能够删除副本并在适当的位置构造
数组
对象

现在,当用户将move构造函数声明为
delete
-d时,在重载解析期间,甚至在解析行中的调用时,都会考虑该构造函数:

array c(array(5));
array(array&&)
将是一个完美匹配…但它被删除,因此重载解析停止(完美匹配),并输出一个错误(函数被删除)

正如评论中所建议的那样,您是否一直在使用C++17标准进行编译

array c(array(5));
将导致有保证的拷贝省略,因为它符合以下场景:

在初始化过程中,如果初始值设定项表达式是prvalue,并且源类型的cv非限定版本与目标类型的类是同一个类,则使用初始值设定项表达式初始化目标对象

使代码严格等效于:

array c(5);
首先,该行:

array c(array(5));
导致使用复制构造函数(因为没有用户声明的移动构造函数)。但是,由于它恰好是
c
对象构造,编译器能够删除副本并在适当的位置构造
数组
对象

现在,当用户将move构造函数声明为
delete
-d时,在重载解析期间,甚至在解析行中的调用时,都会考虑该构造函数:

array c(array(5));
array(array&&)
将是一个完美匹配…但它被删除,因此重载解析停止(完美匹配),并输出一个错误(函数被删除)

正如评论中所建议的那样,您是否一直在使用C++17标准进行编译

array c(array(5));
将导致有保证的拷贝省略,因为它符合以下场景:

在初始化过程中,如果初始值设定项表达式是prvalue,并且源类型的cv非限定版本与目标类型的类是同一个类,则使用初始值设定项表达式初始化目标对象

使代码严格等效于:

array c(5);

此处不生成移动构造函数。迂腐地说,在本例中不声明移动构造函数和赋值

您观察到的是编译器省略了在
数组c(数组(5));
中的复制。有关更多详细信息,请参阅:

在初始化过程中,如果初始值设定项表达式是prvalue,并且源类型的cv非限定版本与目标类型的类相同,则初始值设定项表达式用于初始化目标对象:

T x = T(T(T())); // only one call to default constructor of T, to initialize x


当您执行
array(array&&)=deleted;
时,上面的表达式现在考虑移动构造函数(它以前未声明),并且由于被删除而失败。

此处不生成移动构造函数。在这种情况下,不声明移动构造函数和赋值

您观察到的是编译器省略了在
数组c(数组(5));
中的复制。有关更多详细信息,请参阅:

在初始化过程中,如果初始值设定项表达式是prvalue,并且源类型的cv非限定版本与目标类型的类相同,则初始值设定项表达式用于初始化目标对象:

T x = T(T(T())); // only one call to default constructor of T, to initialize x


当您执行
array(array&&)=deleted;
时,上面的表达式现在考虑移动构造函数(它以前未声明),并且由于被删除而失败。

array c(array(5));
array(5)是右值,因此将调用移动构造函数。
array c(array(5));
array(5)是一个右值,因此将调用移动构造函数。尽管Q没有用C++17标记,但您可能想提到,在C++17中,删除移动构造函数并不重要,即使Q没有用C++17标记,它仍然会删除副本。您可能想提一下,在C++17中,如果移动构造函数是del,则不重要但是,它仍然会删除副本