2016-07-19 8 views
0

Was die richtige Praxis ist die Erfassung Rückgabewert von boost::make_iterator_range in folgenden Szenarien:Der richtige Weg Capturing prvalue in C++ 11

  1. verwendet Wenn in Reichweite basierend for-Schleife:

    for (auto&& val : boost::make_iterator_range(...))// <-- is `auto&&` the right way? 
    
  2. wenn sie als formale Parameter verwendet:

    DoStuff(boost::make_iterator_range(...)); 
    
    template<class Iterator> 
    void DoStuff(Iterator&& it){}// <-- is Iterator&& the right way? 
    

Antwort

0
for (auto&& val : boost::make_iterator_range(...))// <-- is `auto&&` the right way? 

Der Rückgabewert make_iterator_range ist nicht in val gespeichert. val speichert einfach den Rückgabewert der Dereferenzierung der Iteratoren: das Element, nicht den gesamten Bereich.

auto&& erstellt eine Weiterleitungsreferenz für das Element.

DoStuff(boost::make_iterator_range(...)); 

template<class Iterator> 
void DoStuff(Iterator&& it){}// <-- is Iterator&& the right way? 

Unter dem Namen Iterator täuscht über ein Missverständnis: make_itetator_range kein Iterator ist, es ist ein Bereich von Iteratoren definiert ist. Dies gilt nicht, das Verhalten des Codes ändern

template<class Range> 
void DoStuff(Range&& r){} 

, aber es ist wie eine Variable vom Typ mit int namens Double: pointlessly oder aggressiv verwirrend.

In diesem Fall ist in diesem Zusammenhang auch eine Weiterleitungsreferenz.

Eine Weiterleitungsreferenz in einem Typdeduktionskontext kann an einen Lvalue- oder Rvalue-Wert gebunden werden. Es kann auch eine Verlängerung der Referenzlebensdauer verursachen.


In diesen beiden Situationen, auto&& und Range&& sind vernünftige Ansätze, aber würde so auto const&, auto& oder auto im ersten Fall, und in der zweiten Range const& oder Range ihre Vorteile haben. Sie meinen nur verschiedene Dinge.

So sind Ihre Lösungen eine Möglichkeit, die richtig sein kann, aber es gibt keinen "richtigen Weg" für das, was man dort hinstellt. Ich benutze standardmäßig Weiterleitungsreferenzen, aber das ist Geschmackssache: Andere können den Standardwert const& oder Werte wählen. Und in einigen Kontexten wäre auto& korrekt (wo Ihre Schleife den Wert ändert und beabsichtigt, dass diese Änderung beibehalten wird).

+0

1) 'auto' und' Range' können zu unnötigem Kopieren führen 2) 'Bereich const &' macht in nicht änderbar –

+0

In Bezug auf die 'for' Schleife würde' auto' in allen Fällen funktionieren, aber eine Kopie von Das Objekt (das möglicherweise nicht erwünscht ist) und "auto &" funktionieren möglicherweise in einigen Fällen nicht (wenn der Iterator keine Referenz zurückgibt, normalerweise "std :: vector "). – Holt

+0

@alej wenn in Ihrem Anwendungsfall die Kopie nicht notwendig oder gewünscht ist, dann wird es ja. Und die Mutation von Daten, die verworfen werden sollen oder die Sie nicht beabsichtigen zu mutieren, ist normalerweise schlecht. Auch hier kommt es darauf an, welchen Nutzen Sie für die angesprochenen Daten haben. Wenn man auf "const" setzt, bedeutet das, dass man auf nicht-mutierenden Code zurückgreift und ihn mutiert (weg von "const &"), nur wenn man ihn wirklich braucht. Sie * machen verschiedene Dinge *, wenn Ihr Code andere Dinge möchte, verwenden Sie einen anderen. – Yakk

Verwandte Themen