c++ - 当你对检索到的值的表达式进行分支时,是否存在像`if(Value * value = getValue())`这样的习惯用法?

c++ - 当你对检索到的值的表达式进行分支时,是否存在像`if(Value * value = getValue())`这样的习惯用法?,第1张

我经常使用常见的

if (Value * value = getValue())
{
    // do something with value
}
else
{
    // handle lack of value
}

现在,我也常常做

QString error = someFunctionReturningAnErrorString(arg);
if (!error.isEmpty())
{
     // handle the error
}
// empty error means: no error

这一切都很好,但我希望将error变量限定为if - 块。那有一个很好的习语吗?显然,我可以将整个部分包装在另一个块中。

这显然不起作用:

if(QString error = someFunctionReturningAnErrorString(arg), !error.isEmpty())
{
    // handle the error
}
// empty error means: no error

不幸的是(但有充分的理由)QString无法转换为bool,所以这也不起作用:

if(QString error = someFunctionReturningAnErrorString(arg))
{
    // handle the error
}
// empty error means: no error

有什么建议吗?

最佳答案:

6 个答案:

答案 0 :(得分:11)

没有。没有像这样的习语,并且没有像这样的语法

此外,您已经达到了不再值得使代码越来越混淆的程度。

只需像现在一样写下它。

如果确实不希望范围泄漏,请引入新的范围:

{
   const QString error = someFunctionReturningAnErrorString(arg);
   if (!error.isEmpty()) {
      // handle the error
   }
}
// The above-declared `error` doesn't exist down here

我使用这种模式已经相当多了,尽管我已经被指责成瘾,所以请按照你的意愿行事。

答案 1 :(得分:6)

在保持代码可理解的情况下使用该习惯用法的唯一方法是,如果您的函数返回一个可转换为bool的对象,其方式true表示您想要获取分支并{{1} }意味着你不关心它。其他任何东西都会导致只写代码。

可能相关的一个这样的对象恰好是boost::optional。给出:

false

你可以以自然的方式使用你想要的习语:

boost::optional<QString> someFunctionReturningAnErrorString(T arg);

这也有额外的好处,我认为if (auto error = someFunctionReturningAnErrorString(arg)) { // ... } 错误消息在语义上比检查空错误消息更有意义。

答案 2 :(得分:3)

基本上没有干净的方法可以做到。

我建议你只是在if周围定义一个额外的块,但是如果你真的想拥有那个确切的语法,解决办法就是声明你自己的包裹QString的类:

struct ErrorString
{
    ErrorString(QString&& s) : s{move(s)} {}
    operator bool() {return !s.isEmpty();}

    QString s;
};

然后你可以写:

if(ErrorString error = someFunctionReturningAnErrorString(arg))
{
    // handle the error
}
// empty error means: no error

但我并不特别喜欢这个解决方案。

答案 3 :(得分:2)

您可以使用:

for(QString error = someFunctionReturningAnErrorString(arg); !error.isEmpty(); /* too bad 'break' is invalid here */)
{
    // handle the error
    break;
}

但这很难看,让您的代码难以阅读。所以请不要。

答案 4 :(得分:1)

if(auto message = maybe_filter( getError(arg), [](auto&&str){
  return !str.isEmpty();
}) {
}

其中maybe_filter获取T和测试函数并返回optional<T>。如果对optional<T>上的测试函数进行评估,则T为空,否则为T

或者实际上,修改错误,获取API以返回可选字符串。

答案 5 :(得分:0)

您可以使用lambda。

auto error_string_handler = [](QString && error) {
    if (error.isEmpty()) return;
    //...
}

error_string_handler(someFunctionReturningAnErrorString(arg));
本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复