![](/img/trans.png)
[英]Why isn't the copy-constructor called when passing rvalue by value to function
[英]Why isn't rvalue copy constructor used for assignment from temporary?
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&&c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test&z) {
printf(" test(const test&z)\n");
}
test& operator=( test&&e) {
printf(" test& operator=( test&&e)\n");
return *this;
}
};
int main()
{
test o ;
o = 4;
return 0;
}
The Output :
" test() "
" test(int y) "
" test& operator=( test&&e ) "
我认为代码 o = 4 中的这一行正在创建 class(测试)的右值 object 并将其传递给重载运算符(operator =)
但是当我改变
test& operator=( test&&e )
进入
test& operator=( test e )
并再次运行代码:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
o = 4;
return 0;
}
The Output :
" test() "
" test(int y) "
" test& operator=( test e ) "
虽然我预计更改后会出现此 Output:
" test() "
" test(int y) "
" test(test&&c) noexcept "
" test& operator=( test e ) "
因为当我改变
test& operator=( test&&e )
进入
test& operator=( test e )
重载运算符 ( operator = ) 现在将 class 测试的 object 作为参数(按值传递),传递给它的值是一个右值,所以我预计构造函数test(test&&c) noexcept
将被调用
那么为什么构造函数
test(test&&c) noexcept
是不是叫?
解释为什么我有这种期望:
因为当你编写并运行这段代码时:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
test x;
o = move(x); // this function ( move () ) returns an rvalue of its argument
return 0;
}
The Output :
" test() "
" test() "
" test(test&&c) noexcept "
" test& operator=( test e ) "
编辑:这段代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
test x;
o = x;
return 0;
}
The Output :
" test() "
" test() "
" test(const test&z) "
" test& operator=( test e ) "
那么为什么不调用构造函数
test(test&&c) noexcept
呢?
这是由于 C++17 之前的非强制复制 elison。在某些情况下,允许编译器,但不要求省略 class 对象的复制和移动(C++11 起)构造。
您可以通过在第二个示例中提供标志-fno-elide-constructors
来验证这一点。 您将获得预期的output.Demo 。
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
o = 4;
return 0;
}
Output带有-fno-elide-constructors
标志:
test()
test(int y)
test(test&&c) noexcept
test& operator=( test e)
工作演示。
如果您不提供此标志,则允许编译器在这种情况下省略复制/移动构造,因此您将获得您提到的 output。
请注意,从 C++17 开始,由于强制复制 elison ,标志-fno-elide-constructors
不会对 output 产生任何影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.