c++ - C++ 是否可以通过列表初始化调用用户定义的转换函数?

  显示原文与译文双语对照的内容
67 0

这个程序合法?


struct X { X(const X &); };


struct Y { operator X() const; };



int main() {


 X{Y{}};//?? error


}



n2672 之后,并通过缺陷 978修改,13.3.3.1 [over.best.ics]:

但是,考虑构造函数或者用户定义转换函数的参数时考虑第一个参数的第一个参数,只考虑标准转换序列和ellipsis转换序列,只考虑标准转换序列和省略序列。

这似乎相当不合理;它具有使用列表初始化强制转换指定转换的结果是非法的:


void f(X);


f(Y{});//OK


f(X{Y{}});//?? error



在理解 n2640 时,应该能够用列表初始化来替换类型为 X的对象。但是,似乎没有任何方法可以使用列表初始化来构造类型的对象:


X x1(Y{});//OK


X x2 = Y{};//OK


X x3{Y{}};//?? error



这是标准的实际意图;如果不是,它应该读还是读?

时间: 原作者:

130 5

XCode附带的clang版本符合你的解释并拒绝了 X{Y{}}; 。 我在读完标准的相关部分后,几次,FWIW 。

如果修改 X 构造函数以接受两个参数,即 const X&,则clang接受语句 Y y; X{y,y} 。 ( 如果我尝试 X{Y{},Y{}}的话会崩溃。) 。 这似乎与 13.3.3.1 for一致,它要求仅在单个元素的情况下跳过用户定义的转换。

在的用户定义转换已经发生的情况下,对标准和省略转换序列的限制最初被添加到。 或者至少我是这样读 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#84的。

很有趣的是,标准是小心地应用了限制只复制初始化的第二步,从一个已经有正确类型( 通过用户定义的转换获得可能的结果)的临时文件拷贝。 然而对于列表初始化,没有类似的机制似乎存在。

...