当您在检索到的值的表达式上进行分支时,是否有像“if (Value * value = getValue())”这样的成
Is there an idiom like `if (Value * value = getValue())` when you branch on an expression of the retrieved value?
我经常使用公共
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
不能转换为布尔值,所以这也不起作用:
if(QString error = someFunctionReturningAnErrorString(arg))
{
// handle the error
}
// empty error means: no error
有什么建议吗?
No.没有这样的成语,也没有这样的语法!
此外,您已经到了不再值得使您的代码越来越模糊的地步。
只需像现在一样编写即可。
如果您真的不希望示波器泄漏,请引入一个新的示波器:
{
const QString error = someFunctionReturningAnErrorString(arg);
if (!error.isEmpty()) {
// handle the error
}
}
// The above-declared `error` doesn't exist down here
我经常使用这种模式,尽管我被指责为范围成瘾,所以随心所欲。
使用该
习惯用法同时保持代码可理解的唯一方法是,如果您的函数返回一个可转换为 bool 的对象,该对象true
表示您想要获取分支,false
表示您不关心它。其他任何事情都会导致只写代码。
一个可能相关的对象恰好是boost::optional
。鉴于:
boost::optional<QString> someFunctionReturningAnErrorString(T arg);
你可以以自然的方式使用你想要的成语:
if (auto error = someFunctionReturningAnErrorString(arg)) {
// ...
}
这也有一个额外的好处,我认为optional
错误消息比必须检查空错误消息在语义上更有意义。
基本上没有干净的方法可以做到这一点。
我建议你在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
但我不是特别喜欢这个解决方案。
您可以使用:
for(QString error = someFunctionReturningAnErrorString(arg); !error.isEmpty(); /* too bad 'break' is invalid here */)
{
// handle the error
break;
}
但这很丑陋,并且使您的代码难以阅读。所以请不要。
if(auto message = maybe_filter( getError(arg), [](auto&&str){
return !str.isEmpty();
}) {
}
其中maybe_filter
采用T
和测试函数并返回optional<T>
。 如果评估T
上的测试函数会给出 false,则optional<T>
为空,否则T
。
或者实际上,修改获取 API 的错误以返回可选字符串。
您可以使用 lambda。
auto error_string_handler = [](QString && error) {
if (error.isEmpty()) return;
//...
}
error_string_handler(someFunctionReturningAnErrorString(arg));
相关文章:
- 我的简单if-else语句是如何无法访问的代码
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何删除peer if else分支中的冗长句子
- 我似乎对if/else的基本语句有问题:/
- if数组上的随机数
- 将按位if条件转换为普通if条件
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 我怎样才能写得"if not greater than or equal to some value"雄辩?
- 编写 if 语句时出错"'=' : left operand must be l-value"
- 当您在检索到的值的表达式上进行分支时,是否有像“if (Value * value = getValue())”这样的成