directory iterator



  • Hallo Jannik,

    Zeile 29 sollte überflüssig sein. Ich kenne die Implementierung von file::path zwar nicht, aber der Defaultkonstruktor sollte einen 'gültigen' leeren Pfad erzeugen. Dann wird aber auch die statische Methode end() überflüssig, es sei denn wegen 'syntactic sugar'.

    Ist nur formal, aber in Zeile 41 fehlt find_data in der Initialisierungsliste. Es gibt statisch Test (Lint), die das an-meckern würden.

    Die Operatoren operator+ und operator+= sind unnötig, da sie mit advance realisiert werden können. Sie implizieren dem Anwender lediglich, dass operator+ mit O(1)-Komplexität implementiert ist, was aber nicht der Fall ist (nicht sein kann). Das lädt nur zu einem Fehlgebrauch ein.
    Wegen so was hatte ich vor Jahren mal einen dicken Laufzeitfehler in ein Programm eingebaut - ich brauchte mehrere Test beim Kunden, um die Ursache zu ermitteln.

    operator*() und operator->() sollten und können const sein.

    Wenn zwei Iteratoren gleich sind, wenn der Filename gleich ist, so bedeutet dass, dass auch zwei Iteratoren aus unterschiedlichen Directorys gleich sein können. Den operator!= sollte man als !(*this == other) implementieren, um Redundanzen zu vermeiden.

    Gruß
    Werner



  • Hallo Jannik,

    oh, da war aber einer aufmerksam 🤡

    'syntactic sugar'

    cooler begriff 😃

    habe alle fehler bis auf einen ausgebessert 😉

    Die Operatoren operator+ und operator+= sind unnötig, da sie mit advance realisiert werden können. Sie implizieren dem Anwender lediglich, dass operator+ mit O(1)-Komplexität implementiert ist, was aber nicht der Fall ist (nicht sein kann). Das lädt nur zu einem Fehlgebrauch ein.
    Wegen so was hatte ich vor Jahren mal einen dicken Laufzeitfehler in ein Programm eingebaut - ich brauchte mehrere Test beim Kunden, um die Ursache zu ermitteln.

    verstehe das problem, aber da ich std::advance noch nie benutzt habe weiß ich nicht, wie ich es benutzen kann 😕



  • Hallo Jannik,

    gamer8o4 schrieb:

    verstehe das problem, aber da ich std::advance noch nie benutzt habe weiß ich nicht, wie ich es benutzen kann 😕

    Dafür hatte ich Dir in meinem Posting den Link angegeben. Da gibt es auch ein Beispiel.

    oder so:

    int main()
    {
        using namespace std;
        file::path dir( TEXT("C:\\*") );
        int anz = distance( directory_iterator( dir ), directory_iterator() );
        directory_iterator i( dir );
        advance( i, anz/2 ); // inkrementiere den Iterator bis zur Hälfte der Files
        copy( i, directory_iterator(), ostream_iterator< directory_iterator::value_type, wchar_t >( wcout << "Die zweite Haelfte:\n", L"\n" ) );
    
        return 0;
    }
    

    Gruß & Gute Nacht
    Werner



  • Werner Salomon schrieb:

    Sowas nennt man eine 'shared resource'. Und da das so oft vorkommt, muss man das nicht selber coden, denn es gibt in C++11 eine Klasse, die das kann. Das ist der std::shared_ptr<>. Dem (Smart-)Pointer kann man mitgeben, was er tun soll, wenn er bzw. die letzte seiner Kopien gelöscht wird. Hier wäre das die Funktion FindClose .

    Sowas nennt man Move-Only-Type. Man deaktiviert den Kopierkonstruktor/Zuweisungsoperator und schreibt dafür einen Move-Konstruktor und Move-Zuweisungsoperator. Wer die Ressource aus unerfindlichen Gründen sharen will (in deinem Beispiel würde eine Referenz auch genügen), muss das halt mit shared_ptr<directory_iterator> explizit hinschreiben.



  • in deinem Beispiel würde eine Referenz auch genügen

    ein sehr interessanter einfall!! 😮
    ich glaub das schreibe ich mal direkt um, ich mag die idee mit der referenz und es erscheint mir sicherer und schneller also... 🙂



  • Hallo gamer8o4,

    gamer8o4 schrieb:

    in deinem Beispiel würde eine Referenz auch genügen

    ein sehr interessanter einfall!! 😮 ... und es erscheint mir sicherer und schneller

    Ja - interessanter, schneller, verführerischer - quasi die dunkle Seite von C++.

    Ein directory_iterator ist zunächst einmal ein Iterator. Und ein Iterator muss - um dem C++ Standard zu genügen - 'CopyConstructible' sein. Steht ganz vorn bei dem Anforderungen an einen Iterator. Ist er das nicht, so kannst Du noch nicht mal einen std::copy damit aufrufen. Probiere es aus - mache den Kopierkonstruktor privat - Dein Compiler wird das gar nicht übersetzen!

    directory_iterator i = ....;
        copy( i, directory_iterator::end(), ostream_iterator<...>(...) );
    

    Praktisch alle Algorithmen verlangen das, wenn auch in dem einen oder anderen Fall der jeweiligen Implementierung ein moveable ausreichen würde. Und was bitte schön sollte man mit eine shared_ptr<Iterator> anfangen?

    Gruß
    Werner



  • also nicht mit referenzen machen? JA oder NEIN?



  • NEIN


  • Mod

    gamer8o4 schrieb:

    also nicht mit referenzen machen? JA oder NEIN?

    Doppelte Verneinung in schriftlicher Kommunikation ist böse. Denkst du nicht auch, dass das nicht so ist? Ja oder Nein?



  • Oh stimmt ja.
    Fail.
    Ich meine:
    JA



  • also JA, okay ich ändere es 😃


Anmelden zum Antworten