2017-09-26 129 views
3

我雖然對運算符重載,並配備了一個有趣的代碼:邏輯運算符的執行順序

#include <iostream> 

class A { 
public: 
    operator bool() { 
     return true; 
    } 

    bool operator!() { 
     return false; 
    } 
}; 

int main() { 
    A a; 

    if (!a) { 
     std::cout << "HELLO"; 
    } else { 
     std::cout << "WORLD"; 
    } 
    std::cout << std::endl; 

    return 0; 
} 

什麼將被稱爲第一,之後是什麼?爲什麼?這在cppreference的任何地方都有描述嗎?

P.S.對於downvoters和其他誰認爲我不能自己執行此代碼。我可以。我做到了。我已經多次改變它來看它的行爲。所以呢?這不是一個解釋。我已經要求參考哪個明確說明什麼規則這個代碼服從。它在我的機器上的工作方式並不能回答這個問題 - 如果這種方式在不同的環境(操作系統,可能是處理器等)中甚至不可移植?

+1

您是否嘗試過? https://ideone.com/sW8yEm – mch

+2

沒有什麼會被稱爲第一次和之後。只調用'operator!'。 – StoryTeller

+0

@mch是我已經嘗試過,但我無法解釋它是如何工作的。 –

回答

7

工作原理很簡單圖謀後者。編譯器解析源代碼並看到if(!a)。然後它檢查A是否定義了operator!。碰巧它發生了。所以被調用。

如果它已經看到if(a)它將檢查A是否可以轉換爲可以在if的條件下使用的東西。恰恰相反,它確實是可以兌換的。

如果沒有operator!,則編譯器會檢查是否可以將A轉換爲可能在邏輯上取反的東西。 然後轉換到布爾應該已經執行。


順便說一句,轉換即使在令人驚訝的地方也會發生。例如a + 1將被編譯。我想,不是我們想要的。最好僅在預期內容爲bool時才允許它。您可以通過將轉換運算符標記爲:

explicit operator bool() { 
    return true; 
} 
4

!a不過是您定義的a.operator!()的語法糖:這是編譯器的首選選項。

所以轉換爲bool運營商從來不是一個候選人。

您可以通過編寫

if (!(bool)a) {