C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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

这是标准的实际意图吗?如果没有,它应该如何阅读或阅读?

解决方法

13.3.3.1p4的初衷是描述如何在12.3p4中应用以下要求:

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,请注明来意。