隐式类型转换 - 编译器错误

时间:2010-08-20 09:31:44

标签: c++ compiler-errors type-conversion

此问题与this问题有关。以下代码编译精细的VC9编译器,但在与Comeau在线编译时给出错误。任何人都可以告诉我哪一个是正确的,错误是什么意思?

  

错误:含糊不清“?”操作:第二   “TypesafeBool”类型的操作数可以   转换为第三个操作数类型   “bool”,反之亦然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;
}

3 个答案:

答案 0 :(得分:10)

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

这里的Comeau是正确的,因为虽然对观察者来说显而易见的是结果应该采用什么类型,但是三元表达式需要单独使用一个类型,而不需要参考它所使用的类型,它应该选择的类型是不明确的。

答案 1 :(得分:0)

这两种情况都适合运营商?结果必须具有相同的类型。它们的自然类型是TypesafeBool和bool。由于存在从bool到TypesafeBool以及从bool到TypesafeBool的隐式转换,因此存在应该应用的歧义。

C ++规则防止结果随后在预期使用TypesafeBool的上下文中使用,或者已知将结果考虑在内以优先采用第二种方式的事实

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

应该有用。

答案 2 :(得分:0)

要继续@炒作的评论,this article也会提出相同的想法,但构造函数标记为explicit。这消除了你的歧义。

请注意,只要您将b的初始化更改为

,您的示例就可以正常工作
TypesafeBool b( (1==1) ? f() : false );

因为=语法被标记为显式时不允许调用TypesafeBool( bool )语法(因为它在技术上是两个构造函数的组合)。