【问题标题】:Binding const reference to another type将 const 引用绑定到另一种类型
【发布时间】:2021-10-09 20:47:36
【问题描述】:

如何知道是否可以将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 绑定到它

【问题讨论】:

  • "char[10] 不能转换为const char[10]" 为什么不可以呢?您可以随时将const 添加到任何类型
  • 您可以随时将 const 添加到非常量。
  • "对于任何类型的 T,您都可以绑定一个 const 引用?" 为什么不呢?反之亦然,您会遇到麻烦,但这样不会造成任何伤害。
  • @UnholySheep 我使用 std::convertible_to 概念(C++20 的东西)来检查。

标签: c++ const-reference


【解决方案1】:

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

[dcl.init.ref]/4:

给定类型“cv1 T1”和“cv2 T2”,如果 T1 与 T2 相似 ([conv.qual]),或者 T1 是 T2 的基类,则“cv1 T1”与“cv2 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]T1T2引用兼容,因为T2* 可以转换为T1*,因为它只需要将const-qualification 添加到指向的类型,这是标准转换.

正如您在引用的部分中看到的,这不是唯一允许引用绑定的情况 - 例如,另一种情况是将引用绑定到转换结果(包括用户定义的)。 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

【讨论】:

    猜你喜欢
    • 2017-03-12
    • 1970-01-01
    • 2018-08-22
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    相关资源
    最近更新 更多