c++ - 关于引用类型复制初始化的问题

标签 c++ language-lawyer copy-initialization

#include <iostream>
struct Data{};
struct Test{
    Test() = default;
    Test(Data){}
};
int main(){
  Data d;
  Test const& rf = d;
}

考虑以上 code , 标准说:

Otherwise:

  • 5.2.2.1 If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-defined conversion ([dcl.init], [over.match.copy], [over.match.conv]); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference. For this direct-initialization, user-defined conversions are not considered.
  • 5.2.2.2 Otherwise, the initializer expression is implicitly converted to a prvalue of type “cv1 T1”. The temporary materialization conversion is applied and the reference is bound to the result.

那么,上面的案例符合哪一条?初始化表达式通过转换构造函数Test::Test(Data)而不是转换函数转换为类型Test。但是请注意 5.2.2.1 中强调的部分,它表示调用转换函数 的结果然后用于直接初始化引用。在我的示例中,被调用函数正在转换构造函数,因此,结果是转换构造函数的结果。

问题 1:

哪个项目符号涵盖了我的示例? 5.2.2.1 还是 5.2.2.2


5.2.1.2 has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an rvalue or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see [over.match.ref]),

考虑子弹5.2.1.2,它已经涵盖了类型T2是类类型的情况,它可以转换为cv3 T3 通过转换函数

问题 2:

那么,5.2.2.1涵盖T2是类类型,可以通过转换函数转换为目标类型,是不是多余>, 这样的情况在5.2.1.2中已经涵盖了吗?

最佳答案

问题 1

[dcl.init.ref]/5.2.2.1 适用于此。它是涵盖用户定义的转换的段落。可接受的转换机制之一是 16.3.1.4 [over.match.copy],它可以在 T1 上使用转换构造函数。使用此构造函数转换值,并将生成的临时值绑定(bind)到引用。

[dcl.init.ref]/5.2.2.2 适用于隐式转换的情况包括用户定义的转换,例如扩大数字转换。

第 2 期

来自 [dcl.init.ref]:

(5.2.1) If the initializer expression

...

(5.2.1.2) has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an rvalue or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see 16.3.1.6),

跳转到 16.3.1.6 [over.match.ref],这里有很多散文,但这是唯一相关的部分:

(1) ... Assuming that “reference to cv1 T” is the type of the reference being initialized, and “cv S” is the type of the initializer expression, with S a class type, the candidate functions are selected as follows:

(1.1) The conversion functions of S and its base classes are considered. ...

本节的其余部分详细说明了 S 的哪些转换函数可以使用,但这对于示例代码中的情况并不重要。 [over.match.ref] 只考虑用于初始化引用的值类型的转换运算符,这里不是这种情况——Data 没有隐式转换运算符。本节未提及转换 T 的构造函数。

因此 [over.match.ref] 和扩展名 [dcl.init.ref]/5.2.1.2 不适用于这种情况。

关于c++ - 关于引用类型复制初始化的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63460804/

相关文章:

c++ - 插入到特里

c++ - constexpr 函数调用无法编译

c++ - 检查 Linux 功能以设置线程优先级

c++ - 嵌套类的嵌套类的访问权限

c++ - 关于指针类型的问题,该指针类型被预期为运算符前缀++(也适用于后缀++)的操作数类型

c++ - 文件在没有头文件的情况下运行

c - size_t 是否足够大以表示任何类型的大小?

C++(11) : When to use direct or copy initialization if both are perfectly fine

c++ - 为什么复制初始化是这样的?为什么需要复制构造函数?

c++ - 复制初始化 - 从 'int' 到非标量类型的转换