2017-03-15 84 views
3

如果我運行下面的測試女巫Catch字符串皈依

bool eq(int x, int y) { 
    return x == y; 
} 

TEST_CASE("operator vs. function call") { 
    int x = 1; 
    int y = 2; 
    CHECK(x == y); 
    CHECK(eq(x, y)); 
} 

我得到以下輸出

/path/to/MyTest.cpp:8: Failure: 
    CHECK(x == y) 
with expansion: 
    1 == 2 

/path/to/MyTest.cpp:9: Failure: 
    CHECK(eq(x, y)) 
with expansion: 
    false 

爲什麼能趕上轉換xy到字符串運算符表達式x == y但不在函數調用表達式eq(x, y)中?是它在某種程度上可能字符串化以類似的方式函數調用表達式得到的輸出是這樣的:

/path/to/MyTest.cpp:9: Failure: 
    CHECK(eq(x, y)) 
with expansion: 
    eq(1, 2) 

回答

1

有趣的部分是this

#define INTERNAL_CATCH_TEST(expr, resultDisposition, macroName) \ 
    do { \ 
     Catch::ResultBuilder __catchResult(macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition); \ 
     try { \ 
      CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 
      (__catchResult <= expr).endExpression(); \ 
      CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ 
     } \ 
     catch(...) { \ 
      __catchResult.useActiveException(resultDisposition); \ 
     } \ 
     INTERNAL_CATCH_REACT(__catchResult) \ 
    } while(Catch::isTrue(false && static_cast<bool>(!!(expr)))) // expr here is never evaluated at runtime but it forces the compiler to give it a look 
    // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. 

其中exprx == yeq(x, y)

它是如何工作的x == y:由於與==<=較低的優先級(見C++ operator precedence
__catchResult <= expr結果__catchResult <= x == y這相當於(__catchResult <= x) == y__catchResult <= xx包含在==運算符的對象中,該運算符將y傳遞給對象。這就是expr得到解構。其餘的很容易想象。

爲什麼它不爲eq(x, y)工作:

__catchResult <= expr導致__catchResult <= eq(x, y)eq(x, y)首先計算(不拆解)。

出於同樣的原因,如果表達式由圓括號包圍,則它不起作用。例如,(x == y)將導致__catchResult <= (x == y)在這種情況下首先評估x == y(不解構)。這就是爲什麼CHECK((x == y));導致輸出

/path/to/MyTest.cpp:8: Failure: 
    CHECK((x == y)) 
with expansion: 
    false 
2

我懷疑曾經CHECK看到eq(x, y)它只是看到這個函數調用作爲一個表達式的結果。

您可以將您的CHECKINFO看參數,以你的函數調用:

INFO("x:" << x << ", y:" << y); 
CHECK(eq(x, y)); 

將在CHECK通話記錄(顯示「有消息」):

CHECK(eq(x, y)) 
with expansion: 
    false 
with message: 
    x:1, y:2