2010-08-20 99 views
2

此问题与this问题有关。以下代码编译了精美的VC9编译器,但是在与Comeau在线编译时出现错误。任何人都可以告诉我哪一个是正确的,错误的含义是什么?隐式类型转换 - 编译错误

error: ambiguous "?" operation: second operand of type "TypesafeBool" can be converted to third operand type "bool", and vice versa TypesafeBool b = (1==1) ? f() : false;

class TypesafeBool 
{ 
private: 
    bool m_bValue; 
    struct Bool_ { 
     int m_nValue; 
    }; 
    typedef int Bool_::* bool_; 
    inline bool_ True() const { return &Bool_::m_nValue; } 
    inline bool_ False() const { return 0; } 

public: 
    TypesafeBool(const bool bValue) : m_bValue(bValue){} 
    operator bool_() const { return m_bValue ? True() : False(); } 
}; 

TypesafeBool f() 
{ 
    return TypesafeBool(true); 
} 

int main() 
{ 
    TypesafeBool b = (1==1) ? f() : false; 
} 
+0

我觉得Comeau在这种情况下是正确的。即使是g ++和Clang ++也会出现相同的错误。在g ++的情况下,我得到的错误是'错误:操作数为?:具有不同类型'TypesafeBool'和'bool' – 2010-08-20 09:42:13

+2

构造函数应该明确的一个很好的示例 – mukeshkumar 2010-08-20 10:01:38

回答

10

的错误是三元运算符必须有一个单一的类型,你的表达(1=1) ? f() : false有两种类型 - f()的类型为TypesafeBoolfalse的类型是bool。你可以在它们之间进行转换,但Comeau不知道你想使用哪一个。要解决该问题,请将三元组的一侧投射到另一侧:(1=1) ? f() : TypesafeBool(false)

Comeau在这里是正确的,因为虽然观察者对于结果应该采用何种类型是显而易见的,但三元表达式需要自己拥有单一类型,而不必参考它的用途以及它应该选择的类型是含糊不清的。

+0

好的答案。所以这是事实,你可以转换导致问题的两种方式。这真是一个耻辱,因为我想要的是替代'bool'的替代品,它可以为我进行额外的检查。尽管如此,我不能乱抛垃圾代码。 – jkp 2010-08-20 10:13:36

+0

第5.16/3节谈论有关昏昏欲睡细节中的规则:) – Chubsdad 2010-08-20 10:30:49

+0

@jkp:在某些情况下,您可以限制其中一种转换 - 在这种情况下,它必须是隐式的'bool'->'TypesafeBool'转换避免含糊不清。 – 2010-08-20 11:08:13

0

两种情况下的操作员?结果必须具有相同的类型。他们的自然类型是TypesafeBool和bool。由于从bool到TypesafeBool以及从bool到TypesafeBool存在隐式转换,因此存在应该应用的歧义。

C++规则防止这一事实的结果,然后在一个TypesafeBool预期上下文或事实的结果是已知的被考虑用于倾向于第二种方式

TypesafeBool b = (1 == 1)? f() : TypesafeBool(false); 

应工作。

0

继续从@炒作的评论,this article也提出了相同的想法,但建设者标记为explicit。这消除了你的歧义。

请注意,您的例子则做工精细提供你改变b初始化到

TypesafeBool b((1==1) ? f() : false); 

因为=语法不允许调用TypesafeBool(bool)何时标记明确的(因为它在技术上两个构造的组成)。