如何知道是否可以将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]中的引用绑定规则。[dcl.init.ref]/4和[dcl.init.ref]/5。有一长串规则,但与你的问题最相关的是:
[dcl.init.ref]/4:
给定类型"cv1 T1"one_answers"cv2 T2","cv1 T1 reference-related"cv2 T2"如果T1 ([conv.qual]) T2,相似或T1 T2的基类。如果"指向cv2 T2的指针"类型的右值可以通过标准转换序列([conv])转换为"指向cv1 T1的指针"类型,则"cv1 T1"与"cv2 T2"是引用兼容的。
[dcl.init.ref]/5:
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化,如下所示:
-如果引用是左值引用,并且初始化表达式
-是左值引用(但不是位域),并且" cv1 T1 "与" cv2 T2 "是引用兼容的,或者
[…]
则引用绑定到初始化表达式lvalue[…]
在您的示例中,T1
将是const char [10]
,T2
将是char [10]
。T1
与T2
是引用兼容的,因为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