如何解决有关引用类型的复制初始化的问题 问题1:问题2:
#include <iostream>
struct Data{};
struct Test{
Test() = default;
Test(Data){}
};
int main(){
Data d;
Test const& rf = d;
}
考虑以上code,标准中说:
否则:
- 5.2.2.1如果 T1或T2是类类型,并且T1与T2没有引用相关性,则使用用于复制初始化类型为“ cv1 T1”,通过用户定义的转换([dcl.init],[over.match.copy],[over.match.conv]);如果相应的非引用副本初始化格式不正确,则程序格式不正确。 调用转换函数的结果(如非引用副本初始化所述)将用于直接初始化引用。对于这种直接初始化,不考虑用户定义的转换。
- 5.2.2.2否则,初始化程序表达式将隐式转换为类型为“ cv1 T1”的prvalue。应用临时物化转换,并将引用绑定到结果。
那么,上述案件服从哪颗子弹?通过转换构造函数Test
而非Test::Test(Data)
,将初始化程序表达式转换为类型conversion function
。但是请注意5.2.2.1
中强调的部分,它表示调用转换函数的结果然后用于直接初始化引用。在我的示例中,调用的函数是转换构造函数,因此,结果是转换构造函数的结果。
问题1:
哪个子弹涵盖了我的示例? 5.2.2.1
还是5.2.2.2
?
5.2.1.2具有类类型(即T2是类类型),其中T1与T2无关,并且可以转换为类型为“ cv3 T3”的右值或函数左值,其中“ cv1” T1”与“ cv3 T3”(请参见[over.match.ref])参考兼容,
考虑项目符号5.2.1.2
,它已经涵盖了类型T2
是类类型的情况,并且可以通过cv3 T3
将其转换为conversion function
。
问题2:
因此,5.2.2.1
覆盖T2
是否是类类型,并且可以通过conversion function
转换为目标类型,这种情况已经在{{1}中涉及}?
解决方法
问题1
[dcl.init.ref] /5.2.2.1在这里适用。该段涵盖了用户定义的转换。可接受的转换机制之一是16.3.1.4 [over.match.copy],可以在T1
上使用转换构造函数。使用此构造函数转换该值,并将结果临时对象绑定到引用。
[dcl.init.ref] /5.2.2.2适用于隐式转换不的情况,包括用户定义的转换,例如扩展数字转换。
问题2
来自[dcl.init.ref]:
(5.2.1)如果是初始化表达式
...
(5.2.1.2)具有类类型(即
T2
是类类型),其中T1
与T2
无关,并且可以转换为类型为“ cv3T3
”的右值或函数左值,其中“ cv1T1
”与“ cv3T3
”(请参阅16.3.1.6),
跳到16.3.1.6 [over.match.ref],这里有很多散文,但这是唯一相关的部分:
(1)...假设“对 cv1
T
的引用”是要初始化的引用的类型,而“ cv {{1 }}”是初始化表达式的类型,S
是类类型,候选函数的选择如下:(1.1)考虑
S
的转换函数及其基类。 ...
本节的其余部分详细说明可以使用S
的哪些转换函数,但这与示例代码中的情况无关紧要。 [over.match.ref]仅考虑用于初始化引用的值类型的转换运算符,在此情况并非如此-S
没有隐式转换运算符。本节未涉及转换Data
的构造函数。
因此[over.match.ref]和扩展名[dcl.init.ref] /5.2.1.2不适用于这种情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。