1

私のクラスのインターフェースには、存在しないかもしれないオブジェクトへのアクセサが含まれています。現在、null の可能性があるポインターを返します。ポインターをここでstd::optional提案されているように置き換えたいと思います。アクセサーには、Meyers の const_cast トリックを使用して同じコードを 2 回繰り返さないようにするオーバーロードがあります。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 に答える