繁体   English   中英

为什么右值复制构造函数不用于临时赋值?

[英]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

请注意,从 C++17 开始,由于强制复制 elison ,标志-fno-elide-constructors不会对 output 产生任何影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM