C++ 在C+中实现无预处理器的断言+;20
C++知道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(如果 但是,我不知道如何避免表达式的
assert()
,它允许运行时检查根据NDEBUG
编译为零
我希望使用编译器代码替换该宏,并避免使用预处理器。我需要做以下工作:
- 如果表达式的计算结果为
false
- 记录调用断言的代码行
- 放弃对
builds的检查和传递的表达式NDEBUG
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; });