struct A
{
A(const A& src);
A(const char* src);
};
struct B
{
operator A();
operator char*();
};
void test()
{
B v;
A s(v);
}
EDG / Comeau和MSVC允许代码,而GCC 4.4.4,CLANG和BCC 拒绝它是模棱两可的。
C ++委员会成员(最初)回复:
这不是模棱两可的; A(const A&) 构造函数优于A(const char *)构造函数。 const A& 参数直接绑定到结果 的转换功能,所以 考虑转换顺序 是一个用户定义的转换 通过身份转换 (13.3.3.1.4p1)。 const char * 参数是用户定义的转换 然后是资格 转换,所以情况更糟。
然后,他跟进了这个。
实际上,我错了。虽然它是 第二次转换是真的 用户定义的转换中的序列 序列是一个决胜局,看起来更多 密切在13.3.3.2p3, 倒数第二个子弹,揭示了这一点 决胜局只适用于两者 序列包含相同的 用户定义的转换序列,和 在这个例子中并非如此。 因为一个构造函数的转换 sequence使用B ::运算符A()和 其他使用b :: operator char *(), 这两者之间没有决胜局 用户定义的转换序列和 他们很暧昧。
我的问题是这个。
13.3.3.2 p3表明,两个隐式转换序列 同样的形式是难以区分的 转换序列除非其中之一 以下规则适用。
根据我的理解,关键字是“以下规则之一”。 这并不意味着说明“相同转换序列”的子弹 覆盖以上所有内容。我会认为“S1的等级更好 比S2的等级更适用?
答案 0 :(得分:4)
是的,根据我对第13.3.3.2条的解释,预期结果是歧义。
将'B'类型的参数'v'与'A'的任何重载构造函数的参数匹配需要用户定义的转换。这两个序列都具有CONVERSION等级。
我的解释是,以下来自$ 13.3.3.2的引用适用
[...]用户定义的转换序列 U1是更好的转换序列 比另一个用户定义的转换 序列U2 如果它们包含相同的序列 用户定义的转换函数或 构造函数和如果是第二个标准 U1的转换顺序更好 比第二次标准转换 U2序列。
这两个都在类'B'中调用不同的转换函数。因此,我认为第一个条件本身并不满足,因此预期结果是模糊度,因为转换序列中的任何一个都比另一个更好。
答案 1 :(得分:1)
<击> 免责声明:标准在这些部分非常复杂,所以我的理解可能完全错误。
最佳可行功能的标准定义(13.3.3):
鉴于这些定义,一个可行的 函数F1被定义为更好 功能比另一个可行的功能 如果对于所有参数i,则为F2,ICSi(F1)为 转换顺序并不比 ICSi(F2),然后
[...]
- 上下文是按用户定义的转换进行初始化(参见8.5, 13.3.1.5和13.3.1.6)和标准转换序列 将F1 的类型返回到目的地 类型(即实体的类型 被初始化)是更好的 转换顺序比标准 返回的转换顺序 F2类型到目的地类型。
如果我理解正确,那么正在构造的对象的类型在这里具有重要性,这将使A::A(const A &)
成为更好的候选者。
击>
请参阅Johannes的评论,看看为什么这个答案是不正确的:由于Chubsdad指出的原因,这确实含糊不清。