I'm exploring this question: Given char * x, why doesn't const char * && rc2 = x compile?
And I found dcl.init.ref#5.4.4 which says (when we are binding T1 && to T2 lvalue where T2 is not class type, ) and if T1 is reference-related to T2, then if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
Why is there a rule like this? What does this rule want to avoid?
I clearly know that bindings like int i; int && ri = i; is illegal, but my question here is, I expect const char * && rc2 = static_cast<const char *>(x); where static_cast<const char *>(x) should be an prvalue which can bind to rvalue references.
As int i; double && rd = i; is valid, why is char * x; const char * && rc2 = x; invalid?
This rule covers not only cases such as
but also
Here, we don't have an exact match in types: the reference wants to bind to an
int, but the initializer expression has typeconst int. Just like how we don't want the first example to create a temporaryintobject (a copy ofx) and then bindrto that, in the second example we also don't want a temporaryintobject to be created by copyingx.Or, similarly
The idea is that if you have a reference binding that could have been a direct binding if only the reference were of the appropriate kind (i.e. an lvalue reference instead of an rvalue reference) and had the appropriate cv-qualification, then it's probably the programmer's mistake. Creating a temporary object is usually not the desired behavior.
Reference-relatedness captures this notion of "could have been a direct binding".
As for this case that you mentioned:
the same logic applies: the reference-relatedness tells you that this is "too close" to a valid reference binding. If you changed the type of the reference to
const char* const&, then the binding would be valid.