「必要」という言葉は強い言葉です...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を参照してください。