Why does assigning a value to a reference variable being accessed using a temporary object work, but not for a non-reference type?
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? 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. It must not be, since it's a reference to the local n
variable.
But then, the compiler cannot know what n
will refer. One could even do n(rand_bool()? m: _n)
and it must work.
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
. You can't assign to it:
9 = 8; // nope
In your code, a()
is a prvalue or type a
. All of its value member also are. This is why a().m
won't work. m
is a prvalue.
But, a().n
is an lvalue because n
is a lvalue reference. No matter to which variable it points to.
a().n = 20;
works since n
is a lvalue reference type. The compiler does not know that n
is a reference to m
in the implementation. It assumes that n
is a valid lvalue reference and hence accepts that line.
In theory, when you assign to a().n
, you could be assigning to a variable that lives independent of the life of 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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.