将 const 引用绑定到另一种类型

Binding const reference to another type

如何知道是否可以将 const 引用 T1 绑定到 T2

我曾经认为只有当 T2 可转换为 T1 时,您才能将 const 引用 T1 绑定到类型 T2。 但是由于以下编译:

char x[10];
const char (&y)[10] = x;

不应该是这种情况,因为 char[10] 不能转换为 const char[10](如果我错了请纠正我)。那么,能够将 const 引用绑定到不同类型的规则是什么?是否只有一条附加规则,例如:对于任何类型 T 您可以将 const 引用 T 绑定到它 ?

标准描述了[dcl.init.ref]/4 and [dcl.init.ref]/5中的引用绑定规则。规则列表相当长,但与您的问题最相关的部分是:

[dcl.init.ref]/4:

Given types “cv1 T1” and “cv2 T2”, “cv1 T1” is reference-related to “cv2 T2” if T1 is similar ([conv.qual]) to T2, or T1 is a base class of T2. “cv1 T1” is reference-compatible with “cv2 T2” if a prvalue of type “pointer to cv2 T2” can be converted to the type “pointer to cv1 T1” via a standard conversion sequence ([conv]).

[dcl.init.ref]/5:

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

— If the reference is an lvalue reference and the initializer expression
    — is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2”, or
    [...]
then the reference binds to the initializer expression lvalue [...]

在您的情况下,T1 将是 const char [10],而 T2 将是 char [10]T1T2 reference-compatible 因为 T2* 可以转换为 T1*,因为它只需要添加 const-限定为指向类型,这是一个标准的转换。

正如您在引用部分中看到的那样,这并不是允许引用绑定的唯一情况 - 例如,另一种情况是将引用绑定到转换结果(包括用户定义的)。 const 引用也很特殊,因为它们可以绑定到右值。

请注意,这确实与您之前的理解不同 - T2 可能无法转换为 T1,但您仍然可以绑定引用。这是一个例子:

struct A
{
    A(int);
    A(A const&) = delete;
};

struct B : A
{
    B() : A(10) {}
};

B b;
A& ra = b; // ok, binds to base subobject A of b
A a = b;   // fail, A cannot be constructed from an object of B