【发布时间】:2018-02-21 22:00:25
【问题描述】:
我试图了解标准中的哪些规则证明下面的编译器行为是正确的。所以这个问题只是为了得到语言律师的答案。
让我们考虑这两个类:
struct A{
A(int);
};
struct B{
operator int();
};
以下代码编译:
B b;
A a{b};
变量a 直接由b 初始化。根据[dlc.init]/17.6.3:
否则(即,对于剩余的复制初始化情况),可以从源类型转换到目标类型或(当使用转换函数时)到其派生类的用户定义转换序列被枚举为描述在[over.match.copy]中,
我了解直接初始化过程将列出所有用户定义的转换序列,这些转换序列可以执行从B(源类型)到A(目标类型)的转换。 [over.match.copy] 说明在哪里可以找到用户定义的转换函数。
一个用户定义的转换序列只能涉及1个用户定义的转换函数或构造函数。但唯一的转换路径是调用转换构造函数A::A(int) 和转换函数B::operator int()。
因此没有用户定义的转换序列允许从B 转换为A。
为什么按照标准初始化A a{b};可以很好的形成?
【问题讨论】:
-
这里只有一次转化:
B -> int -> A... -
显式调用带有参数的构造函数不是用户定义的转换。
b被转换为int并且int用于调用a的构造函数。 -
@Oliv 你看错了部分。此初始化包含在上一个项目符号中:timsong-cpp.github.io/cppwp/n4659/dcl.init#17.6.2
-
@Oliv 没问题。阅读标准可能会……令人筋疲力尽。
-
1) “(即,对于剩余的复制初始化情况)”非常清楚地表明您在错误的项目符号中。 2)实际上,@NathanOliver 也是错误的子弹。第一个项目符号 [dcl.init]/17.1 涵盖了这一点。这里的实际初始化由[dcl.init.list]/3.6控制。
标签: c++ type-conversion language-lawyer