boost :: optional deprecated get_value_or

时间:2018-04-17 07:48:56

标签: c++ rvalue-reference boost-optional

我怀疑boost :: optional的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;

1 个答案:

答案 0 :(得分: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;

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

的重载
template<typename T>
T const& get_reference_or(boost::optional<T> const&, NonDeduced<T> const&&) = delete;