在 C++20 中实现不带预处理器的断言

Implement assert without preprocessor in C++20

C++ 知道 assert(),它允许运行时检查编译为不依赖于 NDEBUG

我想使用编译器代码替换该宏并避免使用预处理器。我需要执行以下操作:

Breaking/terminating申请简单

在 C++20 中有 std::experimental::source_location,我可以用它来获取断言的代码位置。

可以使用 requiresconstexpr if

完成编译时条件

但是我不知道如何避免对表达式求值。将 myAssert(expression) 作为函数实现时,我需要将表达式结果作为函数参数传递,这意味着它无论如何都会被求值,即使该参数未在函数内部使用。

有没有办法在 C++20 中解决这个问题?

编辑:模板化示例:

template <typename T> requires (gDebug)
void assertTrue(const T& pResult, const std::experimental::source_location& pLocation) noexcept
{
   if (!static_cast<bool>(pResult))
   {
      // error handling
   }
}

template <typename T> requires (!gDebug)
void assertTrue(const T&) noexcept
{
}

我想您是在谈论禁用调试并且希望该函数成为一个 noop 的情况。我看到 2 个选项:

您可以使用宏。宏可能会被滥用,但它们有其用武之地,并且“传递表达式”而不对其求值就是宏的情况。

或者,传递一个 returns 您想要断言的结果的可调用对象。仅在 gDebug == True:

时调用
template <typename F> requires (gDebug)
void assertTrue(const F& f, const std::experimental::source_location& pLocation) noexcept
{
   if (!static_cast<bool>(f()))
   {
      // error handling
   }
}

虽然这会使调用变得相当冗长。例如总是失败的:

assertTrue( [](){ return false; });