将 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中的引用绑定规则。规则列表相当长,但与您的问题最相关的部分是:
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]).
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]
。 T1
与 T2
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
如何知道是否可以将 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中的引用绑定规则。规则列表相当长,但与您的问题最相关的部分是:
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]).
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]
。 T1
与 T2
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