web-dev-qa-db-ja.com

範囲ベースのforループで「auto && e」は何をしますか?

範囲ベースのループでプログラミングするときの私の現在のルールを仮定すると

for(auto const &e :...)ではなくfor(auto &e:...)またはfor(auto a: ...)を使用します。

私はこれを自分の経験と この質問 などに基づいています。

しかし、新しい terse for loops について読んだ後、ルールの_&_を_&&_に置き換えないでください。書かれているように こちら これは マイヤーズのユニバーサルリファレンス のように見えます。

だから、私は自分自身に尋ねます、私の新しいルールはどちらかです

可能な場合はfor(auto const &&e :...)またはfor(auto &&e:...)を使用してください...

またはそれが常に機能するわけではないため、かなり複雑なものにする必要があります

for(auto const &&e :...)またはfor(auto &&e:...)が可能かどうかを確認し、for(auto const &e :...)またはfor(auto &e:...)を検討します。必要な場合にのみ、参照を使用しないでください。

28
towi

Forループで_auto&&_をいつ使用する必要があるかは、ここで Howard Hinnant によって非常にうまく説明されています。

これは何がxにあるかという疑問を残します

_auto &&x = ...expr...
_

実際にです。そして、関数テンプレート定義があったかのように扱われます

_template <class U> void f(const U& u);
_

xのタイプは、uと同じチュールによって推定されます[§7.1.6.4。(7)]。

つまり、それはnotがRValue参照として処理されますが、「ユニバーサル/転送参照」として処理されます-「 参照折りたたみ規則 」が適用されます。

これは

_const auto &&x = ...expr...
_

7.1.6.4。(7)の例のように、少なくとも_const auto &x_の場合。

ただし、PiotrSが質問のコメントで述べているように、修飾子はURef-nessを無効にします。

いいえ、template<class T> void f(const T&&)Tも転送参照も_const auto&&_もないためです。 _T&&_がパラメーター宣言で発生するという事実は、それが転送参照であることを意味するものではありません。 constvolatileのような修飾子のない純粋な_T&&_のみが転送参照です。つまり、template<class T> void f(T&&)または_auto&&_でなければならず、_const T&&_またはconst _auto&&_

6
towi