当前位置: 首页 > 知识库问答 >
问题:

在引用初始化中,“直接绑定”是什么意思?

储毅
2023-03-14

N4527 8.5.3[dcl初始参考]

5对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化,如下所示:

(5.1)-[...]

(5.1.1)-[...]

(5.1.2)-[...]

(5.2)-否则,引用应该是对非易失性const类型的左值引用(即cv1应该是const),或者引用应该是右值引用。

(5.2.1)-如果初始化表达式

(5.2.1.1)-是一个xvalue(但不是位字段)、类prvalue、数组prvalue或函数左值,“cv1 T1”是与“cv2 T2”兼容的参考,或

(5.2.1.2)-具有类别类型(即T2为类别类型),其中T1与T2无关,可转换为“cv3 T3”类型的xvalue、class prvalue或函数左值,其中“cv1 T1”与“cv3 T3”是兼容的参考(见13.3.1.6),

然后,在第一种情况下,引用被绑定到初始值设定项表达式的值,在第二种情况下,引用被绑定到转换的结果(或者,在任何一种情况下,都被绑定到适当的基类子对象)。

(5.2.2)-否则:

(5.2.2.1)-如果T1或T2是类类型,且T1与T2无关,则考虑使用用户定义转换(8.5、13.3.1.4、13.3.1.5)对“cv1 T1”类型的对象进行复制初始化的规则进行用户定义转换;如果相应的非引用副本初始化格式不正确,则程序格式不正确。然后,调用转换函数的结果(如非引用副本初始化所述)用于直接初始化引用。对于这种直接初始化,不考虑用户定义的转换。

(5.2.2.2)-否则,创建“cv1 T1”类型的临时变量,并从初始值设定项表达式复制初始化(8.5)。然后,该引用将绑定到临时。

如果T1与T2相关:

(5.2.2.3)─cv1须与cv2具有相同的履历资格,或较cv2具有更大的履历资格;及

(5.2.2.4)-如果引用为右值引用,则初始值设定项表达式不得为左值。

在除最后一种情况之外的所有情况下(即,从初始化器表达式创建和初始化临时),引用被称为直接绑定到初始化器表达式。

“最后一个案例”是什么意思?5.2.2(包括5.2.2.1和5.2.2.2)或5.2.2.2(仅一个)?

也就是说,5.2.2.1直接绑定吗?

//case 5.2.1.2
struct X{};

struct Y{Y(X);};
const Y& y = X();   // bind directly

struct Z{operator X();};
const X& x = Z();   // bind directly

//case 5.2.2.1
struct A{operator int();};
const int& a = A(); // bind directly or not?

struct B{B(int);};
const B& b = 1;     // bind directly or not?

共有1个答案

狄宪
2023-03-14

“最后一个案例”指的是5.2.2.2:

-否则,将创建"cv1 T1"类型的临时并从初始化器表达式复制初始化(8.5)。然后将引用绑定到临时。

本案取决于前面的条件是否为假,5.2.2.1:

-如果T1T2是一个类类型,并且T1T2不相关。。。

示例的最后两个片段并非如此,因为在第一个片段中,A是类类型,intA没有引用关系。在第二个示例中,B属于类类型,Bint无关。因为这些都是假的,所以5.2.2.2不适用(它们直接绑定)。

 类似资料:
  • 问题内容: 从sys.c第123行: 是数组的通用指针,我可以看到。但是,表示法是什么: 什么是? 编辑: 我在这里学到了另一个C技巧:将被 预处理 并替换为其内容并分配给。 问题答案: 使用 指定的初始化 程序进行 初始化 。 基于范围的初始化是gnu gcc扩展。 要将一系列元素初始化为相同的值,请写入。这是一个GNU扩展。例如, 它不是便携式的。编译与告诉您。 它在这里如何运作? 预处理器在

  • 问题内容: 这是我的代码: 现在的问题是,在初始化程序块中 如果我在之前添加关键字,则可以,但是缺少关键字时会出现错误。 编译器说: 他们为什么不一样? 问题答案: 我不了解设计原理,但可能有助于阅读Java语言规范的相关部分。 8.6。 实例初始化器 实例初始化器可以通过关键字(§15.8.3)引用当前对象,使用关键字(§15.11.2,§15.12),并使用范围内的任何类型变量。 有时会限制使

  • 我使用的是Netbeans,编译器说变量可能没有初始化。这是什么意思?

  • 问题内容: 我们可以将代码放入构造函数或方法或初始化块中。初始化块有什么用?每个Java程序都必须有它吗? 问题答案: 首先,有两种类型的初始化块: 实例初始化块,以及 静态初始化块。 此代码应说明它们的用法以及执行顺序: 印刷品: 如果要运行某些代码而不管使用哪个构造函数,或者想要对匿名类进行一些实例初始化,则实例迭代块很有用。

  • 问题内容: 为什么要使用静态块: 过度: 一个相对于另一个的优点/缺点是什么? 问题答案: 仅在必要时才使用静态初始化程序块。例如,有时您需要执行几个步骤来计算字段的最终值。在这种情况下,您有两个机会:编写一个计算值并将字段声明为的方法,或使用初始化程序块: 在这种情况下,我更喜欢使用静态块,因为方法可能会造成混乱(其他开发人员可能会尝试调用它,尽管在初始化期间只能被调用一次)。 实例字段也是如此

  • 问题内容: ava中的Double Brace初始化语法()是什么? 问题答案: 双括号初始化将创建一个从指定类(外部括号)派生的匿名类,并在该类(内部括号)内提供一个初始化程序块。例如 请注意,使用这种双重括号初始化的作用是创建匿名内部类。创建的类具有this指向周围外部类的隐式指针。尽管通常不是问题,但在某些情况下(例如序列化或垃圾收集时)可能会引起悲伤,值得一提的是。