Catch断言中带参数的函数表达式的字符串转换

String convertion of function expression with parameters in Catch assertion

如果我运行下面测试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

为什么Catch在运算符表达式x == y中可以将xy转换为字符串,而在函数调用表达式eq(x, y)中却不能?是否有可能以类似的方式将函数调用表达式字符串化以获得如下输出:

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

我怀疑一旦 CHECK 看到 eq(x, y) 它只是将此函数调用的结果视为表达式。

您可以在 CHECK 之前插入一个 INFO 以查看函数调用的参数:

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

将在 CHECK 调用时记录(显示 "with message"):

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

有趣的部分是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:
__catchResult <= expr 导致 __catchResult <= x == y 等同于 (__catchResult <= x) == y,因为 <= 的优先级低于 ==(参见 C++ operator precedence)。 __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