web-dev-qa-db-ja.com

std :: as_const()には何が必要ですか?

C++ 11から提供された _std::add_const_ ; C++ 17では、新しい構造- std::as_const() があります。前者は、提供する型の前にconstを追加するだけです。 2つ目は、タイプトレイトではなく、適切な(aのテンプレート)関数です。これは、タイプが右辺値参照の場合を除いて、同じように機能しますが、使用できません。

std::as_const()を提供する動機がよくわかりません。 _std::add_const_に加えてなぜそれが必要なのですか?

20
einpoklum

"Need"は強力な言葉です... _std::as_const_は、必須ではなく便利なので便利です。これは特性ではなく関数なので、typesではなく、実際のvaluesに「constを追加」するために使用できます。

より具体的には、変数_my_value_があり、それをconstとして扱いたいが、コピーしない場合を考えます。 C++ 17以前は、次のように記述する必要があります。

_static_cast<const MyType&>(my_value)
_

タイプを明示的に指定したくない場合は、次のようになります。

_static_cast<std::add_const_t<std::remove_reference_t<decltype(my_value)>> &>(my_value)
_

または、落ち込んで汚くして、Cスタイルのキャストを使用する場合:

_(const decltype(my_value) &) (my_value)
_

これらはすべて迷惑で冗長です。

これらの代わりに、C++ 17を使用してstd::as_const(my_value)を記述します。これですべてです。

ノート:

  • この関数は右辺値参照に対しては正常に機能しますが、無効になっています。その理由は、一時的に過去の破壊への参照を不注意に保持しないようにするためです。 @NicolBolasが説明するように、次のようなものを書いた場合:

    _for(auto &x : std::as_const(returns_container())) { /* do stuff with x */ }
    _

    返されたコンテナの有効期間は、ループの最初の反復の前に終了します。見逃しやすい!

  • 追加(?)情報については、このユーティリティ関数の公式命題を参照してください。AdamDavid Alan MartinおよびAlisdair Meredithによる P007R1

20
einpoklum