在 C++20 中实现不带预处理器的断言
Implement assert without preprocessor in C++20
C++ 知道 assert()
,它允许运行时检查编译为不依赖于 NDEBUG
。
我想使用编译器代码替换该宏并避免使用预处理器。我需要执行以下操作:
- 如果表达式的计算结果为
false
,则中断或终止
- 记录调用断言的代码行
- 放弃
NDEBUG
构建的检查和传递的表达式
Breaking/terminating申请简单
在 C++20 中有 std::experimental::source_location
,我可以用它来获取断言的代码位置。
可以使用 requires
或 constexpr 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; });
C++ 知道 assert()
,它允许运行时检查编译为不依赖于 NDEBUG
。
我想使用编译器代码替换该宏并避免使用预处理器。我需要执行以下操作:
- 如果表达式的计算结果为
false
,则中断或终止
- 记录调用断言的代码行
- 放弃
NDEBUG
构建的检查和传递的表达式
Breaking/terminating申请简单
在 C++20 中有 std::experimental::source_location
,我可以用它来获取断言的代码位置。
可以使用 requires
或 constexpr 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; });