c++ - 使用 std::optional 和条件的安全行为
问题描述
假设我有一个std::optional<Foo>
对象。我想调用其值的方法(Foo 对象),但显然只有在 Foo 存在的情况下。我可以做这样的事情:
std::optional<Foo> test;
/* stuff */
test->method(); //bad! there might not be a Foo in the optional
//object depending on what happened in 'stuff'
if(test) {
if (test->method()) //always valid since 'test' condition was checked
/* do something */
}
if (test && test->method()) //is this good coding practice?
/* do something */
在 SAME 条件语句中包含一个条件(测试)和一个取决于此条件(测试)为真的方法(测试->方法())是否重要?这是不好的编码礼仪吗?
解决方案
您正在寻找的是一个“如果非空则取消引用”运算符。C++ 没有这样的运算符。
有些语言确实有这个运算符。?.
如果 C++ 采用C# 中的运算符,然后std::optional
重载它,这就是代码的样子:
std::optional<foo> test = might_return_a_foo();
//If empty, short-circuit and stop. If not null, call method()
test?.method();
我认为编写显式检查没有任何问题,尽管可以使用适当的 Dereference-if-Not-Null 运算符。optional
如果您确信有问题的对象将存在,您就不会从函数返回;您只需返回一个对象并避免此问题。对象可能不存在这一事实很重要,最好强制程序员为这种情况编写显式处理。
值得注意的是,您可以使事情变得更简洁:
if(auto opt = might_return_a_foo()) {//opt is deduced to be of type std::optional<foo>
//This will only evaluate if opt contains a foo
opt->method();
} else {
//this will only evaluate if opt did NOT contain a foo
std::cerr << "No Object to operate on." << std::endl;
}
此代码非常有效地处理检查,并且当且仅当对象实际存在时,对象optional
在块内可见;if
如果它不存在,那么您可能无论如何都不需要空optional
对象。
推荐阅读
- apache-spark - 为什么从嵌套的 SparkDataframe 中提取值会更改值?
- android - Gradle 构建无法解析所有 Path_provider 依赖项
- ios - Ionic 4 iOS 应用程序对 API 的请求引发错误未知,状态 0
- typegoose - 模型方法采用任何类型的文档或查询
- c# - C# 代码总是从 DateTime.TryParseExact 方法返回 false
- telerik - 在 sitefinity 的内容类型 -> 模块名称中找不到同步的共享点文档以进行编辑
- jmeter - 想要在具有监听器的 JMeter 中执行 TestPlan 并同时生成报告
- javascript - 如何修复“无效的调用对象”
- c# - Swagger codegen 省略空字符串
- json - 如何从 Druid 摄取规范 json 文件中获取模式名称/数据库名称?