Equivalent of const_cast for std::optional

Equivalent of const_cast for std::optional

本文关键字:std optional for cast of const Equivalent      更新时间:2023-10-16

My class' 接口包含一个可能不存在的对象的访问器。目前,它返回一个可能为 null 的指针。我想按照此处的建议将指针替换为std::optional。访问器有一个const重载,它使用 Meyers 的const_cast技巧来避免重复相同的代码两次。

简而言之,我想替换这个:

T const * MyClass::get() const { 
    /* non-trivial */ 
}
T * MyClass::get() { 
    return const_cast<T *>(const_cast<MyClass const *>(this)->get()); 
}

有了这个:

std::optional<T const &> MyClass::get() const { 
    /* non-trivial */ 
}
std::optional<T &> MyClass::get() {
    auto t = const_cast<MyClass const *>(this)->get();
    return t ? std::optional<T &>(const_cast<T &>(* t)) : std::nullopt;
}

替换似乎不令人满意,因为:

  1. 它引入了一个分支;
  2. 额外的复杂性在某种程度上违背了使重载成为轻量级(并且由编译器稍微优化)的目标。

我假设引用的std::optional专用化基本上可以归结为一个具有附加安全性的指针,因此想知道是否有某种方法可以保持指针解决方案的简单性。有没有更令人满意的方法来编写访问器重载以使用std::optional

正如其他人提到的,在 c++14 标准中,使用引用类型实例化std::optional格式不正确。(请参阅 N3690 20.6.2。因此,使用 std::optional 作为指针(指向单个对象的缺失由值 nullptr 表示)的直接替换是不可行的,除非您愿意按值而不是按引用复制对象。

但是,该规范为将来添加此类功能敞开了大门。此外,N7.15 的第 3672 节建议使用 std::reference_wrapper 的解决方法。

更新:此外,@HowardHinnant通知我,包含在标准中已经完全脱离了 c++14。