这应该是不明确的吗? (隐式演员表)

时间:2010-11-24 05:30:16

标签: c++ standards casting

 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的等级更适用?

2 个答案:

答案 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指出的原因,这确实含糊不清。