2013-10-22 49 views
0

我正在閱讀vc crt源代碼,發現下面的代碼片段。什麼是!在下面的宏中呢?

/* Asserts */ 
/* We use !! below to ensure that any overloaded operators used to evaluate expr do not end up at operator || */ 
#define _ASSERT_EXPR(expr, msg) \ 
     (void) ((!!(expr)) || \ 
       (1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, NULL, L"%s", msg)) || \ 
       (_CrtDbgBreak(), 0)) 

#ifndef _ASSERT 
#define _ASSERT(expr) _ASSERT_EXPR((expr), NULL) 
#endif 

我不明白爲什麼我們需要!!在上面的宏中。你能否給一個例子說明一個重載操作符可能在operator ||處結束?

+2

爲什麼downvote沒有解釋?這是一個合法的問題 – xmoex

+2

單個'!'通常會轉換爲'bool',但是會否定。另一個'!'再次否定。因此,'!!'是投給'bool'的簡短手段。 – stefan

回答

2

下面是一個例子:

struct Evil { 
    int number; 
    bool valid; 

    operator int() {return number;} 
    bool operator!() {return !valid;} 
}; 

Evil evil {42, false}; 
if (evil) {std::cout << "It's not zero\n";} 
if (!!evil) {std::cout << "It's valid\n";} 

在第一種情況下,它的經由隱式轉換轉換成布爾到int,如果不是零賦予真。在第二個中,!運算符給出了不同的結果。

+0

該結構的良好名稱。這確實是邪惡的編碼。 – stefan