C++ 在C+中实现无预处理器的断言+;20

C++ 在C+中实现无预处理器的断言+;20,c++,preprocessor,assertion,c++20,C++,Preprocessor,Assertion,C++20,C++知道assert(),它允许运行时检查根据NDEBUG编译为零 我希望使用编译器代码替换该宏,并避免使用预处理器。我需要做以下工作: 如果表达式的计算结果为false 记录调用断言的代码行 放弃对NDEBUGbuilds的检查和传递的表达式 中断/终止应用程序很容易 在C++20中,有一个std::experimental::source\u location,我可以使用它来获取断言的代码位置 编译时条件可以使用requires或constexpr(如果 但是,我不知道如何避免表达式的

C++知道
assert()
,它允许运行时检查根据
NDEBUG
编译为零

我希望使用编译器代码替换该宏,并避免使用预处理器。我需要做以下工作:

  • 如果表达式的计算结果为
    false
  • 记录调用断言的代码行
  • 放弃对
    NDEBUG
    builds的检查和传递的表达式
中断/终止应用程序很容易

在C++20中,有一个
std::experimental::source\u location
,我可以使用它来获取断言的代码位置

编译时条件可以使用
requires
constexpr(如果

但是,我不知道如何避免表达式的计算。在将
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
{
}
模板需要(gDebug)
void assertTrue(常数T和pResult,常数std::实验性::源位置和位置)无例外
{
如果(!静态施法(预施法))
{
//错误处理
}
}
模板需要(!gDebug)
void assertTrue(const T&)无例外
{
}

我想您是在讨论禁用调试并希望函数成为noop的情况。我看到两种选择:

您可以使用宏。宏可能会被误用,但它们有自己的位置,“传递表达式”而不进行求值是宏的一种情况

或者,传递一个可调用函数,该函数返回要断言的结果。仅在
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
   }
}

这是为数不多的宏任务之一。你应该使用适合工作的工具。另外,
assert
是一个运行时的东西,
if-constexpr
需要编译时。@NathanOliver我认为
if-constexpr
的条件应该作为启用/禁用断言本身的(编译时)开关。是
assert
还是预处理器在某种程度上冒犯了你?几十年来,它们一直在为我们其他人工作。@Silicomancer“表达式中的逗号”好吧,这只是标准的
assert
的问题。您可以使用
..
\uu VA\u ARGS\uuu
编写自己的一个。任何东西都不能依赖于
NDEBUG
而不依赖于预处理器,因为
NDEBUG
是预处理器宏。请注意,您的宏只在
gDebug
是依赖值的模板函数中工作。否则该语句不会被丢弃。@NathanOliver无法完全理解。你是说如果constexpr(false)foo()不会被丢弃?是<代码>如果constexpr
仅在模板代码中工作。请看:@NathanOliver谢谢,决定从答案中删除宏
assertTrue( [](){ return false; });