返回带有 ?: 运算符的可选值

Return Optional value with ?: operator

本文关键字:运算符 返回      更新时间:2023-10-16

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

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 : {};
^

你可以显式地将某值返回包装到std::optional中,并回退到无值返回的constexprstd::nullopt

std::nullopt

std::nulloptstd::nullopt_t类型的常量,用于 指示具有未初始化状态的可选类型。

std::nullopt_t

std::nullopt_t是用于指示可选类型的空类类型 具有未初始化状态。特别是,std::optional有一个 构造函数,nullopt_t作为单个参数,这将创建一个 不包含值的可选。

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

应用于您的示例:

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

应该做这个伎俩。

编译器必须从最后两个操作数中推断出三元表达式的结果类型,但它无法从int32_t{}中推断出std::optional<int32_t>

另一方面,int32_tstd::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>{};
}

根据偏好,您当然也可以从decltypeit->second中推断std::optional的模板参数,以进一步减少重复。