[英]How to make a C++ macro which checks condition, prints error if not met and executes user block?
I want to make an assertion-like macro that can be used like so我想制作一个可以像这样使用的类似断言的宏
CHECKED_LOG(window != nullptr, "Window must be initialized")
{
DoSomethingCleanupFunction();
return false;
}
which should expand to something like这应该扩展到类似
if (!(EXPR))
{
LOG_MESSAGE("Error: window != nullptr : " + MSG);
{ /* user block */ }
}
Is there a way to do this without overcomplicating source code with some kind of classes, that use RAII to call all that logic and without double call of !(EXPR)
?有没有办法做到这一点,而无需使用某种类使源代码过于复杂,这些类使用 RAII 来调用所有这些逻辑并且没有
!(EXPR)
的双重调用? I also want that to look natural, not我也希望它看起来很自然,而不是
CHECKEDLOG(...)
Logic();
} // <---- closing brace with opening one
Maybe some preprocessor placeholders for block after the macro of braces magic?也许一些预处理器占位符用于大括号魔术宏之后的块?
In the end i want something like that:最后我想要这样的东西:
bool Initialize()
{
window = InitWindow();
CHECKED_LOG(window != nullptr, "Couldn't initialize window")
{
Stop();
return false;
}
inputHandler = InitInputHandler();
CHECKED_LOG(inputHandler != nullptr, "Couldn't initialize input handler")
{
Stop();
return false;
}
}
and the expansion和扩展
bool Initialize()
{
window = InitWindow();
if (! (window != nullptr))
{
LOG_ERROR("window != nullptr", "Couldn't initialize window");
Stop();
return false;
}
inputHandler = InitInputHandler();
if (! (inputHandler != nullptr))
{
LOG_ERROR("inputHandler != nullptr", "Couldn't initialize input handler");
Stop();
return false;
}
}
Is there a way to do this without overcomplicating source code with some kind of classes, that use RAII to call all that logic and without double call of?(EXPR)?
有没有办法做到这一点,而不用某种类使源代码过于复杂,使用 RAII 来调用所有这些逻辑并且没有双重调用?(EXPR)?
Put LOG_MESSAGE
inside if
with a comma operator that evaluates to true.将
LOG_MESSAGE
放入if
中,并使用计算结果为 true 的逗号运算符。
#define CHECKED_LOG(EXPR, MSG) \
if (!(EXPR) && (LOG_MESSAGE("Error: " #EXPR " : " + MSG), 1))
I would name this macro just IF_NOT_THEN_LOG
or similar, first so that developer knows it's an if
, then - CHECKED
is an adjective, there is no object here, EXPR
is something to do so you if
on that expression.我会将此宏命名为
IF_NOT_THEN_LOG
或类似名称,首先让开发人员知道它是一个if
,然后 - CHECKED
是一个形容词,这里没有 object , if
在那个表达式上, EXPR
是你要做的事情。
Overall, there is a fear associated with such macros.总体而言,存在与此类宏相关的恐惧。 They hide a flow control statement, they usually lead to more complicated code and end up in a spaghetti code.
它们隐藏了一个流程控制语句,它们通常会导致更复杂的代码并最终变成意大利面条式代码。 Lambda, RAII and exception handling were invented into the language because it's simpler, clearer and more safe to work with them.
Lambda、RAII 和异常处理被发明到语言中,因为使用它们更简单、更清晰、更安全。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.