Ist es sicher, push_back ein element aus der selben Vektor?

vector<int> v;
v.push_back(1);
v.push_back(v[0]);

Wenn die zweite push_back bewirkt eine Umverteilung der Verweis auf die erste Ganzzahl in der Vektor wird nicht mehr gültig sein. Also, das ist nicht sicher?

vector<int> v;
v.push_back(1);
v.reserve(v.size() + 1);
v.push_back(v[0]);

Ist es sicher?

  • Da ist ein Fehler in Visual Studio 2010: stackoverflow.com/questions/10218223/...
  • Ein Hinweis: Es gibt derzeit eine Diskussion in der standard-Vorschläge-forum. Als Teil davon, hat jemand eine Beispiel-Implementierung push_back. Ein weiteres Plakat bemerkt einen Fehler, dass es nicht ordnungsgemäß behandelt den Fall, den Sie beschreiben. Niemand sonst, soweit ich das beurteilen kann, argumentiert, dass dies nicht ein bug. Nicht sagen, dass schlüssigen Beweis, nur eine Beobachtung.
  • Tut mir Leid, aber ich weiß nicht, die Antwort zu akzeptieren, denn es gibt immer noch Streit über die richtige Antwort.
  • Ich denke, dass der "bug" war eine Frage der Robustheit arbeiten mit real-world-code, und nicht die Konformität.
  • Ähnlicher Fall: stackoverflow.com/questions/11511510/...
  • Ich wurde gebeten, zu kommentieren, auf diese Frage durch die 5. Kommentar unter: stackoverflow.com/a/18647445/576911. Ich bin dabei und upvoting jede Antwort, die derzeit sagt: ja, es ist sicher zu push_back ein element aus dem gleichen Vektor.
  • Werden Sie dann sagen, dass jeder Requires: Bedingung und Voraussetzung in der gesamten Norm gilt nur, wenn die Funktion aufgerufen wird, und Sie zu brechen, bevor die Funktion zurückkehrt, ist erlaubt, es sei denn er läuft in Konflikt mit irgendeiner anderen Regel? Denn das ist die einzige Möglichkeit, die Standard interpretiert wurde dies zulassen.
  • Ich sage, dass wenn dies nicht erlaubt, es müsste eine Erfordert verbieten es. Zum Beispiel siehe Tabelle 100 - Sequence-Anforderungen für container, a.insert(p,i,j), pre: i und j sind nicht Iteratoren in einem. Siehe auch [res.auf.Argumente]/p1/b3, der effektiv sagt, dass, wenn Sie tun v.push_back(move(v[0])); dann ist es nicht garantiert, um zu arbeiten. Wenn Sie etwas bewegen, die std::lib ist zulässig, zu vermuten, was Sie bewegt, ist wirklich ein prvalue. Aber ich kenne keine Einschränkungen in Bezug auf v.push_back(v[0]);. Zusätzlich ich bin mir bewusst, dass alle std::lib implementors hart arbeiten, um diese Arbeit zu machen.
  • Sie sagen also, dass, obwohl der Standard verlangt die übergabe eines gültigen Verweis auf push_back, es ist ok, um pass ein, dass Sie wissen, unterliegt der drohenden Abwertung? Mit dieser begrenzten Sicht auf die Funktionen Requires aka Voraussetzungen, ich könnte brechen die meisten, wenn nicht alle algorithmen beschrieben in der Norm.
  • Wenn Sie nicht einverstanden sind mit dem, was der standard sagt, oder auch wenn Sie einverstanden mit dem standard, aber glaube nicht, dass er sagt es deutlich genug, das ist immer eine option für Sie: cplusplus.github.io/LWG/lwg-aktiv.html#submit_issue habe ich diese Möglichkeit, mich öfter als ich mich erinnern kann. Manchmal erfolgreich, manchmal nicht. Wenn Sie möchten, zu diskutieren, was der standard sagt, oder was er sagen sollte, ALSO nicht ein wirksames forum. Unser Gespräch hat keine normative Bedeutung. Sie können aber eine chance haben, in eine normative Wirkung, indem Sie den link oben.
  • Sind Sie sicher, dass Sie konnte? Es gibt durchaus ein paar Regeln in der Algorithmen-Bibliothek über das, was Ihre Funktionen sind erlaubt, das zu tun.
  • ja, ziemlich sicher. Ich werde arbeiten müssen, bis es ein Beispiel nach der Arbeit und sehen, ob Sie können den Namen für jede Regel, die er verletzt.
  • Requires: ist eine Voraussetzung, nicht eine invariante.
  • Es gibt zwei verschiedene Definitionen für das Wort Invarianten auch. Eines ist eine Tatsache, ist immer wahr, wenn eine bestimmte Codezeile erreicht ist. Voraussetzung sicher qualifiziert, da diese Art von invariante. Ein weiterer ist die Tatsache, dass hält vom Ende der Konstruktor bis zum Beginn der Zerstörung, möglicherweise mit Ausnahmen, während ein lock gehalten wird. Diese zweite definition nicht wirklich zu Funktion Argumente (andere als Konstruktor-Argumente, die gespeichert werden für die Lebensdauer des Objekts an, zum Beispiel mit Mitglieder-Daten der Referenz-Typ).
  • Eine Voraussetzung gelten nicht als invariante. Eine invariante auf der anderen Seite ist auch eine Voraussetzung. Dass gesagt wird, eine invariante kann für jedes sub-Programm, ob eine Klasse, ein Modul, Methode, Funktion, Schleife oder einfache code-block. In Bezug auf die C++ - Spezifikationen, ich glaube Requires: bedeutet pre-Zustand, und nicht unveränderlich. Die Voraussetzung muss nur zu halten, die unmittelbar vor der Ausführung des sub-Programms.
  • Ist ein "loop-invariant" eine invariante? Ja, Voraussetzung ist eine invariante -- für mindestens einen trivialen (leeren) basic-block an den Anfang der Funktion.
  • Könnte mir jemand erklären, warum das erste Beispiel in der Frage wäre unsicher? Ich bin ein bisschen ein Neuling, und ich habe Probleme, warum es vielleicht sein könnte ist unsicher. Danke!
  • Wenn push_back bewirkt, dass der Vektor zu erreichen, die Kapazität, der Vektor Zuweisung einer neuen größeren Puffer, kopiere die alten Daten, und löschen Sie dann die alten Puffer. Dann wird es fügen das neue element ein. Das problem ist, das neue element ist ein Verweis auf Daten in der alten-Puffer, die gerade gelöscht wurde. Es sei denn, push_back macht eine Kopie des Werts, der vor dem löschen, es wird dann eine schlechte Referenz.

InformationsquelleAutor Neil Kirk | 2013-09-13
Schreibe einen Kommentar