【问题标题】:Binding rvalue to lvalue reference将右值绑定到左值引用
【发布时间】:2017-12-06 15:54:24
【问题描述】:

我有以下 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");
}

运行代码时,我在“测试开始”和“测试结束”输出之间得到以下输出:

构造函数:1

复制构造函数:10

复制构造函数:10

析构函数:10

析构函数:10

析构函数:1

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

值得一提的是,当test函数的参数const A &amp;a改为A &amp;a(不是常量)时,程序无法编译,报错如下:

错误 C2664: 'A test(A &,A,A *)' : 无法将参数 1 从 'int' 到 'A &'

如何解释这种行为?

具体来说:

  1. 为什么将整数1 发送到test 会使A 的参数构造函数A(int i) 工作(并且仅在使用const 时)?

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

【问题讨论】:

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


【解决方案1】:

好吧,使用第一个参数1 调用test 会导致创建rvalue 类型为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);

rvalue 可以分配给rvalue referencelvalue reference to const

  • 为什么会这样? rvalues 是临时对象或文字。如果此代码合法

    int &amp;r = 5

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


const A& x = 1; //compile
x = 2;         //error!
A&& xxx = 1; //compile
A& xx  = 1; //does not compile.

关于第二个问题。您正在从test 返回A 的副本,因此*c 触发c 副本的构造。 尝试从 test 返回引用 A 以查看构造函数没有被调用。

【讨论】:

  • A&amp;&amp; xxx = 1; A xxxx = 1;有什么区别?
  • @dragonxlwang 第一个是对rvalue 的引用(= 符号右侧的临时匿名1),第二个是普通 1 被复制到的变量。
猜你喜欢
  • 2014-10-31
  • 2017-04-13
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多