大佬教程收集整理的这篇文章主要介绍了c – 是否可以通过列表初始化调用用户定义的转换函数?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
struct X { X(const X &); }; struct Y { operator X() const; }; int main() { X{Y{}}; // ?? error }
在n2672之后,经过defect 978修订,13.3.3.1 [over.best.ics]具有:
这看起来很不正常;它的结果是使用列表初始化强制转换指定转换是非法的:
void f(X); f(Y{}); // OK f(X{Y{}}); // ?? error
据我所知n2640,列表初始化应该能够替换直接初始化和复制初始化的所有用法,但似乎没有办法只使用列表初始化从类型为Y的对象构造类型为X的对象:
X x1(Y{}); // OK X x2 = Y{}; // OK X x3{Y{}}; // ?? error
这是标准的实际意图吗?如果没有,它应该如何阅读或阅读?
在defect 84之前,13.3.3.1p4几乎是纯粹的信息:
这是因为13.3.1.4第1段子弹2和13.3.1.5p1b1将候选函数限制为S类,产生类型T,其中S是初始化表达式的类类型,T是要初始化的对象的类型,所以没有其他用户定义的转换转换序列的自由度. (13.3.1.4p1b1是另一个问题;见下文).
缺陷84通过限制允许的转换序列来修复auto_ptr漏洞(即auto_ptr< Derived> – > auto_ptr< Base> – > auto_ptr_ref< Base> – > auto_ptr< Base>,通过两个转换函数和转换构造函数)类复制初始化的第二步中构造函数的单个参数(此处为auto_ptr的构造函数< Base>采用auto_ptr_ref< Base>,不允许使用转换函数将其参数从auto_ptr转换为< Base>):
n2672然后补充:
这显然是混淆的,因为13.3.1.3和13.3.1.7中唯一的候选转换是构造函数,而不是转换函数. Defect 978纠正了这个问题:
这也使13.3.1.4p1b1与12.3p4一致,否则将允许在复制初始化中无限制地应用转换构造函数:
struct S { S(int); }; struct T { T(S); }; void f(T); f(0); // copy-construct T by (convert int to S); error by 12.3p4
问题是13.3.1.7所指的语言是什么意思. X正在复制或移动构造,因此语言不包括应用用户定义的转换来到达其X参数. std :: initializer_list没有转换函数,因此该语言必须适用于其他内容;如果不打算排除转换函数,则必须排除转换构造函数:
struct R {}; struct S { S(R); }; struct T { T(const T &); T(S); }; void f(T); void g(R r) { f({r}); }
列表初始化有两个可用的构造函数; T :: T(const T&)和T :: T(S).通过排除复制构造函数(因为它的参数需要通过用户定义的转换序列进行转换),我们确保只考虑正确的T :: T(S)构造函数.如果没有这种语言,列表初始化将是模糊的.将初始化列表作为单个参数传递的方式类似:
struct U { U(std::initializer_list<int>); }; struct V { V(const V &); V(U); }; void h(V); h({{1,2,3}});
编辑:经历了这一切,我在Johannes Schaub找到a discussion确认了这个分析:
好的,关闭提交缺陷报告.我打算建议拆分13.3.3.1p4:
以上是大佬教程为你收集整理的c – 是否可以通过列表初始化调用用户定义的转换函数?全部内容,希望文章能够帮你解决c – 是否可以通过列表初始化调用用户定义的转换函数?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。