为什么在初始化期间应用了用户定义的转换?(Why does user

编程入门 行业动态 更新时间:2024-10-28 09:25:11
为什么在初始化期间应用了用户定义的转换?(Why does user-defined conversion applied during the initialization?)

以下代码正常工作:

#include <iostream> struct B { operator int() { return int(); } }; struct A { A(int, int){ std::cout << "A(int, int)" << std::endl; } }; A a({B(), B()}); int main() { }

并产生输出:

A(int, int)

DEMO

但我不明白为什么? 标准说的是:

但是,在13.3.1.3中调用复制/移动类复制初始化的第二步中的临时对象时,在考虑构造函数或用户定义的转换函数的参数时,初始值列表作为单个参数,或者当初始化符列表恰好具有一个元素,并且转换为某个类X或对(可能是cv-qualified)X的引用仅作为X构造函数的第一个参数考虑标准转换序列和省略号转换序列

所以在我们的例子中,我们考虑了构造函数的参数(它是{B(), B()} )。 更确切地说,我们通过初始化列表作为单个参数(我引用的规则中的第二个例子)。 现在,我们需要将initializer-list的第一个元素(类型B临时)转换为int ,唯一的方法是应用用户定义的转换( B::operator int() )。 但是,正如规则末尾所说,我引用了标准转换序列和省略号转换序列 。 因为,该代码不应该工作,它应该抛出像A(int, int)这样的错误是不可行的或排序的。

怎么了。 可能是一个错误?

The following code works fine:

#include <iostream> struct B { operator int() { return int(); } }; struct A { A(int, int){ std::cout << "A(int, int)" << std::endl; } }; A a({B(), B()}); int main() { }

and produces output:

A(int, int)

DEMO

But I can't get why? What the Standard says is:

However, when considering the argument of a constructor or user-defined conversion function that is a candidate by 13.3.1.3 when invoked for the copying/moving of the temporary in the second step of a class copy-initialization, by 13.3.1.7 when passing the initializer list as a single argument or when the initializer list has exactly one element and a conversion to some class X or reference to (possibly cv-qualified) X is considered for the first parameter of a constructor of X [...] only standard conversion sequences and ellipsis conversion sequences are considered

So in our case we considered the argument of the constructor (it was {B(), B()}). More precisely, we passed initializer-list as a single argument (the second case in the rule I cited). Now, we need to convert the first element of the initializer-list (temporary of type B) to int and the only way to do that is to apply user-defined convertion (B::operator int()). But, as said at the end of rule that I cited only standard conversion sequences and ellipsis conversion sequences was considered. Since, that code shouldn't work, it should throw the error like A(int, int) is not viable or sort of.

What's wrong. May be it's a bug?

最满意答案

措辞有缺陷,并用C ++ 14改变。 现在[over.best.ics] / 4读取

但是,如果目标是

构造函数的第一个参数 [...]

并且构造函数或用户定义的转换函数是一个候选者

13.3.1.3, 当参数是类复制初始化的第二步中的临时参数时 , 13.3.1.4,13.3.1.5或13.3.1.6(在所有情况下)或者 13.3.1.7的第二阶段,当初始化列表只有一个元素,目标是类X的构造函数的第一个参数,并且转换为X或引用(可能是cv-qualified) X ,

不考虑用户定义的转换序列。 [ 注意:这些规则阻止在重载解析期间应用多个用户定义的转换,从而避免无限递归。 - 结束注释 ]

B()到int的转换不在此范围内 - 粗体短语仅适用于在复制初始化期间将引用绑定到临时对象。 但是, Clang根据上述拒绝了这个示例代码 :

class A; struct B { operator A(); }; struct A { A(A const&){} }; A a{B()};

The wording was defective and changed with C++14. Now [over.best.ics]/4 reads

However, if the target is

the first parameter of a constructor or […]

and the constructor or user-defined conversion function is a candidate by

13.3.1.3, when the argument is the temporary in the second step of a class copy-initialization, 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), or the second phase of 13.3.1.7 when the initializer list has exactly one element, and the target is the first parameter of a constructor of class X, and the conversion is to X or reference to (possibly cv-qualified) X,

user-defined conversion sequences are not considered. [ Note: These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion. — end note ]

The conversion of B() to int is not covered by this - the bold phrase only appertains to the binding of a reference to a temporary during copy-initialization. However, Clang rejects this sample code according to the above:

class A; struct B { operator A(); }; struct A { A(A const&){} }; A a{B()};

更多推荐

本文发布于:2023-08-06 21:11:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1455318.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:用了   初始化   定义   用户   user

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!