相当于std :: optional的const_cast

时间:2013-09-18 22:39:33

标签: c++ pointers const optional c++14

我的类'接口包括一个可能不存在的对象的访问器。目前,它返回一个可能为null的指针。我想用建议herestd::optional替换指针。访问者具有const重载,使用Meyers' const_cast trick来避免重复相同的代码两次。

简而言之,我想替换它:

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. 额外的复杂性在某种程度上违背了使重载变得轻量级(并且由编译器轻易优化)的目标。
  3. 我假设参考的std::optional特化可以基本上归结为一个增加安全性和奇迹的指针,因此如果有某种方法可以保持指针解决方案的简单性。是否有更令人满意的方法来编写访问者重载以使用std::optional

1 个答案:

答案 0 :(得分:2)

正如其他人所提到的,在c ++ 14标准中,使用引用类型实例化std::optional是不正确的。 (参见N3690 20.6.2。)因此,使用std::optional作为指针的插入式替换(指向缺少由值nullptr表示的单个对象)是除非你愿意按价值而不是通过参考来复制对象,否则不可行。

但是,该规范为将来添加此类功能留下了空间。此外,section 7.15N3672建议使用std::reference_wrapper解决方法。

更新:此外,@ HowardHinnant告诉我,标准中包含的内容已经完全被c ++ 14所取代。