32

C++11 は私たちに与えてくれましたstd::add_const。C++17 では、新しい構造 - がありstd::as_const()ます。前者constは、提供するタイプの前に a を追加するだけです。2番目のものは、型特性ではなく、適切な(aのテンプレート)関数であり、同じことを行うようです-型が右辺値参照である場合を除いて、その場合は使用できません。

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

4

2 に答える 2

37

「必要」という言葉は強い言葉です...std::as_const厳密に必要というわけではなく、便利だから存在します。これは trait ではなく関数であるため、typesではなく実際のに「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 */ }
    

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

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

于 2018-11-23T16:46:48.333 に答える