[英]Why is a reference type an lvalue when accessed with a temporary object?
Why does assigning a value to a reference variable being accessed using a temporary object work, but not for a non-reference type?为什么将值分配给使用临时 object 访问的引用变量有效,但不适用于非引用类型?
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;
}
But is a().n
truely a temporary?但是a().n
真的是暂时的吗? Consider this code:考虑这段代码:
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;
}
The line (2)
clearly shows that .n
is not a temporary.第(2)
行清楚地表明.n
不是临时的。 It must not be, since it's a reference to the local n
variable.它一定不是,因为它是对局部n
变量的引用。
But then, the compiler cannot know what n
will refer.但是,编译器无法知道n
将引用什么。 One could even do n(rand_bool()? m: _n)
and it must work.甚至可以做n(rand_bool()? m: _n)
并且它必须工作。
The compile instead uses the type system to know what should be assigned or not.相反,编译使用类型系统来知道应该分配什么。
For example, the literal 9
is a pr-value of type int
.例如,文字9
是int
类型的 pr 值。 You can't assign to it:你不能分配给它:
9 = 8; // nope
In your code, a()
is a prvalue or type a
.在您的代码中, a()
是纯右值或类型a
。 All of its value member also are.它的所有价值成员也都是。 This is why a().m
won't work.这就是a().m
不起作用的原因。 m
is a prvalue. m
是纯右值。
But, a().n
is an lvalue because n
is a lvalue reference.但是, a().n
是一个左值,因为n
是一个左值引用。 No matter to which variable it points to.不管它指向哪个变量。
a().n = 20;
works since n
is a lvalue reference type.因为n
是左值引用类型,所以有效。 The compiler does not know that n
is a reference to m
in the implementation.编译器不知道n
在实现中是对m
的引用。 It assumes that n
is a valid lvalue reference and hence accepts that line.它假定n
是一个有效的左值引用,因此接受该行。
In theory, when you assign to a().n
, you could be assigning to a variable that lives independent of the life of a()
.理论上,当您分配给a().n
时,您可以分配给一个独立于a()
生命周期的变量。 The compiler has no way of assessing that and will be in the way of the programmer if it didn't accept that line.编译器无法评估这一点,如果它不接受该行,它将妨碍程序员。 Imagine the use case below:想象一下下面的用例:
// 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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.