boost :: optional deprecated get_value_or

Rai*_*Rai 5 c++ rvalue-reference boost-optional

我怀疑boost :: optional's get_value_or已被弃用,因为如果将rvalue作为default参数传递则不安全.但是,有时可以引用可选值或默认备选方案.

以下是安全的吗?

template<typename T>
T const& get_reference_or(boost::optional<T> const& opt, T const& alt)
{
    if (opt) return opt.get();
    else return alt;
}

template<typename T>
T const& get_reference_or(boost::optional<T> const&, T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 3

正如所写,您的代码在类型推导方面存在问题,因为T可以从两个参数中推导。但假设你实际上T只从可选的中推导出来:

template <class T>
struct NonDeducedHelper { using type = T; };

template <class T>
using NonDeduced = typename NonDeducedHelper<T>::type;

template<typename T>
T const& get_reference_or(boost::optional<T> const& opt, NonDeduced<T> const& alt)
{
    if (opt) return opt.get();
    else return alt;
}

template<typename T>
T const& get_reference_or(boost::optional<T> const&, NonDeduced<T>&&) = delete;
Run Code Online (Sandbox Code Playgroud)

然后,代码几乎是安全的,因为当const使用非右值作为 的默认值时get_reference_or,它将尝试使用已删除的重载并无法编译。但是,为了 100% 安全,您还应该删除const右值的重载:

template<typename T>
T const& get_reference_or(boost::optional<T> const&, NonDeduced<T> const&&) = delete;
Run Code Online (Sandbox Code Playgroud)