为什么引用类型在使用临时对象访问时是左值



为什么为使用临时对象访问的引用变量赋值有效,而不适用于非引用类型?

class a
{
public:
int m;
int &n;
a():m(2),n(m)
{
cout<< "A's constructor"<<endl;
}
};
int main()
{
// a().m = 6; // this gives an error that a temporary object is being used 
// as an lvalue
a().n = 20;   // But this line works
return 0;
}

但是a().n真的是暂时的吗?考虑这个代码:

class a
{
public:
int m;
int &n;
a():m(2),n(m)
{
cout<< "A's constructor"<<endl;
}
a(int& _n):m(2),n(_n)
{
cout<< "A's constructor"<<endl;
}
};
int main()
{
a().n = 20;   // (1)
int n = 0;
a(n).n        // (2)
return 0;
}

线(2)清楚地表明.n不是暂时的。它不能是,因为它是对本地n变量的引用。

但是,编译器无法知道n将引用什么。一个人甚至可以做n(rand_bool() ? m : _n),它必须工作。

相反,编译使用类型系统来知道应该分配什么或不应该分配什么。

例如,文字9是类型为int的pr值。你不能分配给它:

9 = 8; // nope

在代码中,a()是一个prvalue或类型a。它的所有值成员也是。这就是a().m不起作用的原因。m是一个prvalue。

但是,a().n是左值,因为n是左值引用。无论它指向哪个变量。

a().n = 20;

由于CCD_ 15是左值引用类型,因此有效。编译器不知道n在实现中是对m的引用。它假定n是一个有效的左值引用,因此接受该行。

理论上,当你分配给a().n时,你可以分配给一个独立于a()寿命的变量。编译器无法评估这一点,如果它不接受这一行,就会妨碍程序员。想象一下下面的用例:

// Global variable.
int gv;
class a
{
public:
int m;
int &n;
a():m(2), n(gv)  // n is a reference to the global variable.
{
cout<< "A's constructor"<<endl;
}
};
int main()
{
a().n = 20;   // Changes gv. It is a valid operation.
return 0;
}

最新更新