考虑以下代码:
struct S
{
template <typename T>
operator T() const
{ return {}; }
};
struct R
{
R() = default;
R(const R&) = default;
R(R&&) = default;
R(bool) {}
};
standard上的哪些是为以下行为定义的规则?
S s;
R r1 = s; // (1) passes: T = R
R r2(s); // (2) ambiguity: T = R or bool?
为什么没有(1)引起歧义问题(假设R
也可以bool
初始化)?我最近为一个类似的问题写了一个答案,但我很好奇为什么(1)在这种情况下不像(2)那样,我不知道它在哪里在标准上描述了。
答案 0 :(得分:2)
8.5 / 15-16:
调用大括号或等于初始化程序或条件的
=
形式的初始化以及... 副本初始化表单中出现的初始化
T x(a);
T x{a};
以及......被称为直接初始化。
因此R r1 = s;
是复制初始化,R r2(s);
是直接初始化。关于第17段:
如果目标类型是(可能是cv限定的)类类型:
如果初始化是直接初始化,或者它是复制初始化,其中源类型的cv-nonqualified版本与目标类的构造函数相同,或者是派生类,构造函数被考虑。列举了适用的构造函数(13.3.1.3),并通过重载解析(13.3)选择最佳构造函数。
否则(即,对于剩余的复制初始化情况),可以从源类型转换为目标类型或(当使用转换函数时)到其派生类的用户定义的转换序列是按照13.3.1.4的描述进行枚举,最好的一个是通过重载决议(13.3)选择的。
因此,直接初始化会查看R
的所有构造函数并最终变得模糊,而复制初始化显式尝试直接将表达式转换为R
并成功。