2010-08-20 125 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)何時標記明確的(因爲它在技術上兩個構造的組成)。