
Ali
const auto&
würde ausreichen, wenn ich Nur-Lese-Operationen durchführen möchte. Allerdings bin ich darauf gestoßen
for (auto&& e : v) // v is non-const
ein paar Mal in letzter Zeit. Das wundert mich:
Ist es möglich, dass in einigen obskuren Eckfällen ein Leistungsvorteil durch die Verwendung von Weiterleitungsreferenzen im Vergleich zu auto&
oder const auto&
?
(shared_ptr
ist ein Verdächtiger für obskure Eckfälle)
Aktualisieren
Zwei Beispiele, die ich in meinen Favoriten gefunden habe:
Irgendein Nachteil der Verwendung von const-Referenzen beim Iterieren über Basistypen?
Kann ich mit einer bereichsbasierten for-Schleife problemlos über die Werte einer Karte iterieren?
Konzentrieren Sie sich bitte auf die Frage: Warum sollte ich auto&& in bereichsbasierten for-Schleifen verwenden wollen?

Howard Hinnant
Der einzige Vorteil, den ich sehe, ist, wenn der Sequenz-Iterator eine Proxy-Referenz zurückgibt und Sie diese Referenz auf nicht konstante Weise bearbeiten müssen. Betrachten Sie zum Beispiel:
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto& e : v)
e = true;
}
Dies wird nicht kompiliert, weil rvalue vector<bool>::reference
von der zurückgekehrt iterator
wird nicht an eine nicht konstante lvalue-Referenz gebunden. Aber das wird funktionieren:
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto&& e : v)
e = true;
}
Abgesehen davon würde ich nicht auf diese Weise codieren, es sei denn, Sie wüssten, dass Sie einen solchen Anwendungsfall erfüllen müssen. Dh ich würde das nicht unentgeltlich machen, weil es tut die Leute dazu bringen, sich zu fragen, was du vorhast. Und wenn ich es getan habe, würde es nicht schaden, einen Kommentar dazu hinzuzufügen, warum:
#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;
}
Bearbeiten
Dieser letzte Fall von mir sollte wirklich eine Vorlage sein, um Sinn zu machen. Wenn Sie wissen, dass die Schleife immer eine Proxy-Referenz verarbeitet, dann auto
würde auch funktionieren auto&&
. Aber wenn die Schleife manchmal Nicht-Proxy-Referenzen und manchmal Proxy-Referenzen handhabte, dann denke ich auto&&
wäre die Lösung der Wahl.
Verwenden auto&&
oder universelle Referenzen mit einem bereichsbasierten for
-loop hat den Vorteil, dass Sie erfassen, was Sie erhalten. Für die meisten Arten von Iteratoren erhalten Sie wahrscheinlich entweder a T&
oder ein T const&
für irgendeinen Typ T
. Der interessante Fall ist, wo die Dereferenzierung eines Iterators einen temporären Wert ergibt: C++ 2011 hat gelockerte Anforderungen und Iteratoren müssen nicht unbedingt einen lvalue liefern. Die Verwendung von universellen Referenzen entspricht der Argumentweiterleitung in 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;
}
Das Funktionsobjekt f
behandeln kann T&
, T const&
und T
anders. Warum sollte der Körper eines Bereichs basieren for
-Schleife anders sein? Um tatsächlich davon zu profitieren, den Typ anhand universeller Referenzen abgeleitet zu haben, müssten Sie diese natürlich entsprechend weitergeben:
for (auto&& x: range) {
f(std::forward<decltype(x)>(x));
}
Natürlich mit std::forward()
bedeutet, dass Sie alle zurückgegebenen Werte akzeptieren, von denen verschoben werden soll. Ob solche Objekte in Nicht-Template-Code viel Sinn machen, weiß ich (noch?) nicht. Ich kann mir vorstellen, dass die Verwendung universeller Referenzen dem Compiler mehr Informationen bieten kann, um das Richtige zu tun. Bei Template-Code bleibt es außen vor, Entscheidungen darüber zu treffen, was mit den Objekten passieren soll.
benutze ich praktisch immer auto&&
. Warum von einem Grenzfall gebissen werden, wenn Sie nicht müssen? Es ist auch kürzer zum Tippen und ich finde es einfach … transparenter. Wenn Sie verwenden auto&& x
dann weißt du das x
ist genau *it
jedes Mal.
9856200cookie-checkWas ist der Vorteil der Verwendung von Weiterleitungsreferenzen in bereichsbasierten for-Schleifen?yes
Tust du Ja wirklich “oft” sehen?
– Leichtigkeitsrennen im Orbit
29. Oktober 2012 um 22:44 Uhr
Ich bin mir nicht sicher, ob Ihre Frage genügend Kontext enthält, um einzuschätzen, wie “verrückt” es ist, wo Sie es sehen.
– Leichtigkeitsrennen im Orbit
29. Oktober 2012 um 22:49 Uhr
@LightnessRacesinOrbit Lange Rede kurzer Sinn: Warum sollte ich verwenden wollen
auto&&
in bereichsbasierten for-Schleifen?– Ali
29. Oktober 2012 um 22:52 Uhr