使用?:运算符返回可选值

时间:2017-07-29 13:33:07

标签: c++ optional c++17

我经常需要为函数使用可选类型:

std::optional<int32_t> get(const std::string& field)
{
    auto it = map.find(field);
    if (it != map.end()) return it->second;
    return {};
}

有没有办法在一行中返回可选值?例如这样:

std::optional<int32_t> get(const std::string& field)
{
    auto it = map.find(field);
    return it != map.end() ? it->second : {};
}

导致错误

error: expected primary-expression before '{' token
return it != map.end() ? it->second : {};
                                      ^

2 个答案:

答案 0 :(得分:26)

您可以将某个值的回复显式换行到std::optional,然后返回到constexpr std::nullopt以获得无值回报。

  

<强> std::nullopt

     

std::nulloptstd::nullopt_t类型的常量   表示未初始化状态的可选类型。

     

...

     

<强> std::nullopt_t

     

std::nullopt_t是一个空类类型,用于表示可选类型   未初始化的国家。特别是,std::optional有一个   使用nullopt_t作为单个参数的构造函数,它创建一个   可选的,不包含值。

使用这种方法,三元运算符调用的true子句显式返回带有some值的std::optional,因此编译器可以推导出模板参数/ wrapped类型(在此示例中为:int32_t )从提供的包装值的类型,意味着您不需要明确指定它。

应用于您的示例:

return it != map.end() ? std::optional(it->second) : std::nullopt;

// alternatively
return it != map.end() ? std::make_optional(it->second) : std::nullopt;

答案 1 :(得分:20)

std::optional<int32_t>

应该这样做。

编译器必须从最后两个操作数推导出三元表达式的结果类型,但是它无法从int32_t{}推导出int32_t

另一方面,

std::optional<int32_t>std::optional<int32_t>确实具有所需的常见类型auto get(const std::string& field) { auto it = map.find(field); return it != map.end() ? it->second : std::optional<int32_t>{}; }

相关有趣的事实:您可以避免重复使用自动返回类型扣除的类型:

std::optional

根据偏好情况,您当然也可以使用it->seconddecltype推断user_likes的模板参数,以进一步减少重复次数。