将右值绑定到左值参考

时间:2017-07-03 11:37:36

标签: c++ constructor type-conversion copy-constructor

我有以下c ++代码(VS2013):

#include <iostream>
using namespace std;

class A {
    int i;
public:
    A(int i) : i(i) {
        cout << "Constructor: " << i << endl;
    }
    A(const A &o) : i(o.i) {
        cout << "Copy constructor: " << i << endl;
    }
    ~A() {
        cout << "Destructor: " << i << endl;
    }
};

A test(const A &a, A b, A *c) {
    return *c;
}

int main() {
    A b(10);
    cout << "START OF TEST" << endl;
    test(1, b, &b);
    cout << "END OF TEST" << endl;
    system("pause");
}

运行代码时,我在&#34; START OF TEST&#34;之间得到以下输出。和&#34;测试结束&#34;输出:

  

构造函数:1

     

复制构造函数:10

     

复制构造函数:10

     

析构函数:10

     

析构函数:10

     

析构函数:1

构建了3个对象:1个使用整数1,2个使用类A的对象(i = 10)。

值得一提的是,当test函数的参数const A &a更改为A &a(不是常量)时,程序无法编译,给出以下错误:

  

错误C2664:&#39;测试(A&amp;,A,A *)&#39; :无法转换参数1   &#39; INT&#39;到&#39; A&amp;&#39;

这种行为是如何解释的?

具体做法是:

  1. 为什么向1发送整数test会使A的参数构造函数A(int i)正常工作(并且仅在使用const时)?< / p>

  2. 为什么A&#39的复制构造函数A(const A&amp; o)工作两次? (调用test时会发生一次运行,而返回*c时会发生另一次运行。)

1 个答案:

答案 0 :(得分:5)

好吧,使用第一个参数test调用1会导致创建类型为rvalue的{​​{1}}。可以将右值分配给A,但不能分配给普通const lvalue reference引用。如果您希望在不使用lvalue的情况下进行编译,则必须指定该参数是const引用。

rvalue错误提供了更多信息:

g++

error: cannot bind non-const lvalue reference of type ‘A&’ to an rvalue of type ‘A’ test(A(1), b, &b); 可以分配给rvaluervalue reference

  • 为什么? lvalue reference to const是临时对象或文字。如果此代码合法

    rvalues = 5

    然后您就可以修改int &r。 另一方面,5禁止对他们引用的对象进行任何更改,因此您可以将它们绑定到lvalue references to const

rvalue

关于第二个问题。您将从const A& x = 1; //compile x = 2; //error! A&& xxx = 1; //compile A& xx = 1; //does not compile. 返回A的副本,以便test触发构建*c的副本。 尝试从c返回引用A,以查看未调用构造函数。