145

const auto&読み取り専用操作を実行したい場合は十分です。しかし、私はぶつかった

for (auto&& e : v)  // v is non-const

最近数回。これは私が不思議に思う:

またはと比較して、転送参照を使用すると、いくつかのあいまいなコーナーケースでパフォーマンス上の利点がある可能性はありますauto&const auto&?

(shared_ptrあいまいなコーナーケースの疑いがあります)


お気に入りで見つけた 2 つの例を更新します。

基本型を反復するときに const 参照を使用することの欠点はありますか?
範囲ベースの for ループを使用して、マップの値を簡単に反復処理できますか?

質問に集中してください:なぜ auto&& を範囲ベースの for ループで使用したいのですか?

4

3 に答える 3

115

私が見ることができる唯一の利点は、シーケンス反復子がプロキシ参照を返し、その参照を非定数の方法で操作する必要がある場合です。たとえば、次のように考えてください。

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto& e : v)
        e = true;
}

vector<bool>::referenceから返された右辺値iteratorが非 const 左辺値参照にバインドされないため、これはコンパイルされません。しかし、これはうまくいきます:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto&& e : v)
        e = true;
}

そうは言っても、そのようなユースケースを満たす必要があることがわかっていない限り、この方法でコーディングすることはありません。つまり、あなたが何をしているのだろうと人々に疑問を抱かせるので、私はこれを不当に行うつもりはありませんそして、私がそうした場合、その理由についてコメントを含めても問題ありません。

#include <vector>

int main()
{
    std::vector<bool> v(10);
    // using auto&& so that I can handle the rvalue reference
    //   returned for the vector<bool> case
    for (auto&& e : v)
        e = true;
}

編集

私のこの最後のケースは、意味をなすためのテンプレートになるはずです。ループが常にプロキシ参照を処理していることがわかっている場合はautoauto&&. しかし、ループが時々非プロキシ参照を処理し、時にはプロキシ参照を処理していたとき、私auto&&は選択の解決策になると思います.

于 2012-10-29T22:50:12.777 に答える
28

範囲ベースのループでauto&&またはユニバーサル参照を使用するとfor、得られるものをキャプチャできるという利点があります。ほとんどの種類のイテレータでは、おそらく aT&または aT const&のいずれかの type を取得しますT。興味深いケースは、反復子を逆参照すると一時的な値が生成される場合です。C++ 2011 では要件が緩和され、反復子は必ずしも左辺値を生成する必要はありません。ユニバーサル リファレンスの使用は、 の引数転送と一致しますstd::for_each()

template <typename InIt, typename F>
F std::for_each(InIt it, InIt end, F f) {
    for (; it != end; ++it) {
        f(*it); // <---------------------- here
    }
    return f;
}

関数オブジェクトは、 、、および を異なる方法でf扱うことができます。範囲ベースのループの本体が異なるのはなぜですか? もちろん、ユニバーサル参照を使用して型を推定したことを実際に利用するには、それに応じてそれらを渡す必要があります。T&T const&Tfor

for (auto&& x: range) {
    f(std::forward<decltype(x)>(x));
}

もちろん、 usingstd::forward()は、移動元の戻り値を受け入れることを意味します。このようなオブジェクトがテンプレート以外のコードで意味があるかどうかはわかりません (まだ?)。ユニバーサル参照を使用すると、正しいことを行うためにコンパイラにより多くの情報を提供できると想像できます。テンプレート化されたコードでは、オブジェクトで何が起こるべきかについて決定を下すことはありません。

于 2012-10-30T19:35:53.543 に答える
8

私は事実上常に使用しますauto&&。必要がないのに、エッジケースに噛まれるのはなぜですか? 入力するのも短く、単純に...透明性が高いと思います。を使用すると、毎回正確に であることがauto&& xわかります。x*it

于 2012-10-30T19:40:39.170 に答える