Ich verstehe völlig, dass diese Frage viel gestellt wurde, aber ich frage nach einer bestimmten Variante und mein Such-foo hat aufgegeben, da ich nur Algorithmen gefunden habe, die eine existierende anhängen Vektor zu einem anderen, aber nicht einer von einer Funktion zurückgegeben.
Ich habe diese Funktion, die alle Dateien in einem Verzeichnis auflistet:
%Vor%das sich intern (für Unterverzeichnisse) aufrufen kann.
Ich brauche eine kurze Möglichkeit, den zurückgegebenen Wert an den Vektor des Aufrufers anzufügen. Ich habe so etwas im Kopf (aber natürlich existiert es nicht :():
%Vor%Ich befürchte, dass das Speichern des Rückgabewerts und das Einfügen in die Dateiliste zu einer schlechten Performance führen würde. Was ich meine, ist dies:
%Vor%Danke!
PS: Ich zwinge mich nicht dazu, Vektor zu verwenden, irgendeinen anderen Container, der gleich gut funktioniert und verhindern kann, dass der potentielle große Kopiervorgang für mich in Ordnung ist.
Wenn Sie in der Lage sind, scanDir
zu ändern, machen Sie eine (Template-) Funktion, die einen Ausgabe-Iterator akzeptiert:
Sie haben den zusätzlichen Vorteil, dass Sie alle Arten von Datenstrukturen wie
ausfüllen können %Vor%usw.
BEARBEITEN (siehe Kommentar ...)
Um diese Funktion für die Initialisierung von Klassenmitgliedern zu verwenden, können Sie sie entweder im Konstruktor wie in
aufrufen %Vor%oder mithilfe einer Wrapper-Funktion
%Vor%Ich würde die erste Version aus Gründen der Leistung (und anderer) bevorzugen ...
PS: Ich zwinge mich nicht dazu, Vektor zu verwenden, irgendeinen anderen Container, der gleich gut funktioniert und verhindern kann, dass der potentielle große Kopiervorgang für mich in Ordnung ist.
Nun, wenn Sie list
verwenden und a.splice(a.end(), b);
aufrufen, vermeiden Sie den Kopiervorgang vollständig. A list
ist im Allgemeinen eine verkettete Liste und nicht wie bei einem vector
ein Array. Dies hat also viele Auswirkungen auf die Leistung und Nutzung. Aber Spleiß läuft in O (1), das ist ein netter Vorteil.
Verwenden Sie std :: list und hängen Sie an, indem Sie std :: list :: splice verwenden.
Von den Dokumenten für Spleiß :
Die Operation beinhaltet weder die Konstruktion noch die Zerstörung eines Elementobjekts und wird, abgesehen von der dritten Version, in konstanter Zeit ausgeführt.
Anstelle von
%Vor%Sie können
tun %Vor%und fahren Sie mit der Kopie fort:
%Vor%Dies ist vielleicht nicht die einfachste mögliche Lösung, aber was ist mit etwas Ähnlichem wie C # 's StringBuilder?
Machen Sie eine list<vector<string> >
, dann können Sie alle Vektoren, die Sie von Ihren Aufrufen erhalten, an scanDir()
an die Liste anhängen.
Wenn Sie am Ende unbedingt einen einzelnen Vektor haben müssen, können Sie, sobald Sie einen neuen Vektor erstellt haben, diesen groß genug zuweisen, damit er nicht in der Größe geändert werden muss, und Ihr fertiges Produkt zusammenstellen.
Alternativ können Sie eine neue Klasse erstellen (falls erforderlich, die vom Vektor & lt; T & gt; abgeleitet wird) und intern die Liste & lt; vector & lt; T & gt; & gt; um die Elemente zu speichern. Dann würden Sie Ihre Iteratoren einfach durch die Elemente in der ersten Liste durchlaufen lassen, und wenn sie das Ende erreicht haben, gehen Sie zu den Elementen in der nächsten Liste und geben nur container :: end zurück, wenn Sie das Ende der letzten Liste erreicht haben.
Ich weiß, dass dies Ihre Frage nicht direkt beantwortet, aber in Bezug auf Ihr zugrunde liegendes Ziel möchten Sie vielleicht Ihre Funktion einfach in Bezug auf boost :: filesystem neu implementieren. Der Verzeichnis-Iterator ist bereits rekursiv, sodass Sie keine eigenen rekursiven Aufrufe durchführen müssen. Sie könnten einfach eine Liste in einer Schleife über den Iterator auffüllen. Es gibt eine Beispielimplementierung von ls: Ссылка
Sie erhalten außerdem den zusätzlichen Vorteil der (theoretischen) Plattformunabhängigkeit, der relativ breiten Akzeptanz (Fehler werden schneller durch mehr Adoption behoben), usw.