我经常使用普通的
if (Value * value = getValue())
{
// do something with value
}
else
{
// handle lack of value
}
Run Code Online (Sandbox Code Playgroud)
现在,我也经常这样做
QString error = someFunctionReturningAnErrorString(arg);
if (!error.isEmpty())
{
// handle the error
}
// empty error means: no error
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但我希望error变量的范围是if-block.那有一个很好的习语吗?显然,我可以将整个部分包装在另一个块中.
显然,这不起作用:
if(QString error = someFunctionReturningAnErrorString(arg), !error.isEmpty())
{
// handle the error
}
// empty error means: no error
Run Code Online (Sandbox Code Playgroud)
不幸的是(但有充分的理由)QString无法转换为bool,所以这也不起作用:
if(QString error = someFunctionReturningAnErrorString(arg))
{
// handle the error
}
// empty error means: no error
Run Code Online (Sandbox Code Playgroud)
有什么建议?
Lig*_*ica 10
没有.这样没有成语,没有这样的语法!
此外,您已经达到了不再值得使代码越来越混淆的程度.
只需像现在一样写它.
如果您真的不希望范围泄漏,请引入新范围:
{
const QString error = someFunctionReturningAnErrorString(arg);
if (!error.isEmpty()) {
// handle the error
}
}
// The above-declared `error` doesn't exist down here
Run Code Online (Sandbox Code Playgroud)
我使用这种模式已经相当多了,尽管我已经被指责成瘾,所以请按照你的意愿行事.
在保持代码可理解的情况下使用该习惯用法的唯一方法是,如果您的函数返回一个可转换为bool的对象,其方式true表明您想要获取分支并且false意味着您不关心它.其他任何东西都只会导致只写代码.
可能相关的一个这样的对象恰好是boost::optional.鉴于:
boost::optional<QString> someFunctionReturningAnErrorString(T arg);
Run Code Online (Sandbox Code Playgroud)
你可以用自然的方式使用你想要的习语:
if (auto error = someFunctionReturningAnErrorString(arg)) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
这也有额外的好处,我认为optional错误消息在语义上比检查空错误消息更有意义.