1

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

简而言之,我想替换它:

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

4

1 回答 1

2

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

但是,该规范为将来添加此类功能打开了大门。此外,N3672第 7.15节建议使用.std::reference_wrapper

更新:此外,@HowardHinnant 告诉我,标准中包含的内容已完全从 c++14 中剔除。

于 2013-09-26T17:15:07.637 回答