使用std :: optional和conditional

时间:2018-08-09 17:58:12

标签: c++

假设我有一个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条件语句中,包括条件(测试)和依赖于此条件(测试)的方法(测试-> method())是否重要?是不好的编码吗?礼节?

1 个答案:

答案 0 :(得分:3)

您要查找的是“非空时取消引用”运算符。 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对象。