4

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

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

  • 如果表达式计算结果为,则中断或终止false
  • 记录调用断言的代码行
  • 放弃检查和传递的NDEBUG构建表达式

中断/终止应用程序很容易。

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

编译时条件可以使用requiresorconstexpr 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
{
}
4

1 回答 1

2

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

您可以使用宏。宏可能会被滥用,但它们有自己的位置,并且“传递表达式”而不评估它是宏的情况。

或者,传递一个可调用的对象,该可调用对象返回您要为其断言的结果。仅在以下情况下调用它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; });
于 2020-07-27T14:40:42.337 回答