复制列表初始化的隐式转换的等级是多少
What's the rank of implicitly conversion for copy-list-initialization
#include <iostream>
struct A{
A(int){
}
};
struct B{
B() = default;
B(A){
}
B(B const&){}
B(B&&){}
};
int main(){
B b({0});
}
对于给定的代码,候选函数为:
#1 B::B(A)
#2 B::B(const B&)
#3 B::B(B&&)
根据标准,对于#1,类型A的对象由{0}复制列表初始化为A a = {0}
,A::A(int)
被考虑用于初始化,因此只有#1内的标准转换。对于#2,它是引用表单braced-init-list
的初始化,这是[dcl.init.list]的原因
否则,如果T是引用类型,则生成由T引用的类型的prvalue。prvalue通过复制列表初始化或直接列表初始化来初始化其结果对象,具体取决于引用的初始化类型。然后使用prvalue直接初始化引用。[注意:与往常一样,如果引用类型是对非常量类型的左值引用,则绑定将失败,并且程序格式错误。—尾注]
所以它等于const B& = {0}
,在这个初始化中,转换函数是B::B(A)
,参数是0
,所以B tmp = {0}
和"B::B(A("被认为是参数由参数0
初始化为A parameter = 0
。
否则(即,对于剩余的副本初始化情况(,可以从源类型转换为目标类型或(当使用转换函数时(转换为其派生类的用户定义的转换序列将按照[over.match.copy]中的描述进行枚举,并通过重载解析选择最佳转换序列。。。
所以在#2中有一个用户定义的转换,#3的情况与#2的情况相同,并且根据[over.ics.rank],
标准转换序列是比用户定义的转换序列或省略号转换序列更好的转换序列,并且。。。
标准转换比用户定义的转换好,所以#1应该比#2和#3好,但实际上,g++报告调用不明确,为什么?错误消息为:
main.cpp: In function ‘int main()’:
main.cpp:12:10: error: call of overloaded ‘B(<brace-enclosed initializer list>)’ is ambiguous
B b({0});
^
main.cpp:8:3: note: candidate: B::B(A)
B(A){
^
main.cpp:6:8: note: candidate: constexpr B::B(const B&)
struct B{
^
main.cpp:6:8: note: candidate: constexpr B::B(B&&)
所有三个转换{0} -> A
、{0} -> const B&
、{0} -> B&&
都是用户定义的转换。
要将{0}
转换为A
,将发生另一个重载解决方案,并且这一次您将面对三个构造函数A(int)
、A(const A&)
和A(A&&)
。由于0 -> int
是标准转换,而0 -> const A&
和0 -> A&&
都是用户定义的转换,因此转换0 -> int
获胜,选择A(int)
将{0}
转换为A
。
你的困惑源于混淆了两个超负荷的解决方案。
答案在这里,因为参数是初始值设定项列表,所以在重载解析时执行[over.ics.list]规则。
[over.ics.list]/6
- 否则,如果参数是非聚合类X并且重载解析per[over.match.list]从参数初始值设定项列表中选择一个X的最佳构造函数C来执行X类型对象的初始化:
- 如果C不是初始化器列表构造函数,并且初始化器列表有一个类型为cv U的单个元素,其中U是X或从X派生的类,则隐式转换序列在U是X的情况下具有精确匹配秩,或者在U从X派生时具有转换秩
- 否则,隐式转换序列是用户定义的转换序列,第二个标准转换序列是身份转换
因此,对于这三个candicate构造函数,它们的参数都是非aggerate类类型,因此隐式转换序列用于将初始化器列表的单个元素转换为构造函数CCD_ 25的参数的构造函数的相应参数类型,因此这些转换序列都是用户定义的转换序列。所以它们的等级是不可区分的。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 从 long 转换C++位集构造函数的复杂性是多少?
- 在 C/C++ 中,混合类型整数数学所需的最小类型向上转换是多少?
- 如何将特定数量的字符转换为大写或小写,并计算单词有多少个大写和小写字母
- 转换为 int 或其他类型的某些内存地址的十六进制值的大小是多少?
- 从 std::unique_ptr<Dervied> 转换为 std::unique_ptr 的成本是多少<Base>?