bitset statt vector<bool>?



  • zeig mal code



  • Ich glaube nicht, dass ich eine falsche Syntax verwende. Aber vielleicht irre ich mich ja.

    std::vector<bool> mAscending;     
    // dialog.mComboBoxColumnX->currentItem() gibt einen int zurück
    mAscending.at(dialog.mComboBoxColumn1->currentItem()).swap(mAscending.at(dialog.mComboBoxColumn2->currentItem()));
    // liefert: error: `swap' undeclared (first use this function)    
    std::swap(mAscending.at(dialog.mComboBoxColumn1->currentItem()),mAscending.at(dialog.mComboBoxColumn2->currentItem()));
    // liefert: error: invalid initialization of non-const reference of type 'std::_Bit_reference&' from a temporary of type 'std::_Bit_reference'
    

    Tschau Gartenzwerg



  • Gartenzwerg schrieb:

    mAscending.at(dialog.mComboBoxColumn1->currentItem()).swap(mAscending.at(dialog.mComboBoxColumn2->currentItem()));

    Seit wann hat denn bool eine Methode mit Namen swap?

    std::swap(
    mAscending.at(
    dialog.mComboBoxColumn1->currentItem()
    ),
    mAscending.at(
    dialog.mComboBoxColumn2->currentItem()
    )
    );

    Hat vector<bool> denn ein at?

    btw: man verwendet at sowieso nicht - sondern man verwendet immer den operator[] - wir sind ja nicht bei Java



  • const_reference at(size_type pos) const;
    reference at(size_type pos);
    incl out of Range test



  • Shade Of Mine schrieb:

    Gartenzwerg schrieb:

    mAscending.at(dialog.mComboBoxColumn1->currentItem()).swap(mAscending.at(dialog.mComboBoxColumn2->currentItem()));

    Seit wann hat denn bool eine Methode mit Namen swap?

    Ok, mein Fehler. Ich habe dies von einem anderen Vektor übernommen, der eine Klasse enthält, in der swap definiert wurde.

    Shade Of Mine schrieb:

    Gartenzwerg schrieb:

    std::swap(
    mAscending.at(
    dialog.mComboBoxColumn1->currentItem()
    ),
    mAscending.at(
    dialog.mComboBoxColumn2->currentItem()
    )
    );

    Hat vector<bool> denn ein at?

    btw: man verwendet at sowieso nicht - sondern man verwendet immer den operator[] - wir sind ja nicht bei Java

    Wieso sollte vector<bool> kein at haben? Dann scheint es aber kein ordentlicher Vektor zu sein, die anderen Vektoren haben nämlich ein at.
    Wieso verwendet man at nicht? IMHO führt at eine Überprüfung durch, ob auch ein Index gewählt wurde, der möglich ist. Der []-Operator macht dies nicht.

    Habe jetzt auf folgendes geändert:

    std::swap(
    mAscending[dialog.mComboBoxColumn1->currentItem()],
    mAscending[dialog.mComboBoxColumn2->currentItem()]);
    

    Ergebnis:
    error: invalid initialization of non-const reference of type 'std::_Bit_reference&' from a temporary of type 'std::_Bit_reference'
    /usr/include/g++/bits/stl_algobase.h:121: error: in passing argument 1 of `void std::swap(_Tp&, _Tp&) [with _Tp = std::_Bit_reference]'

    Tschau Gartenzwerg



  • Shade Of Mine schrieb:

    btw: man verwendet at sowieso nicht - sondern man verwendet immer den operator[] - wir sind ja nicht bei Java

    gibts dafür irgendwelche plausiblen gründe? (wills nur wissen, weil mich die aussage ziemlich verwundert)



  • Wenn du ordentlich programmierst, benötigst du nicht bei jedem Zugriff eine Überprüfung
    auf Gültigkeit des Indexes und somit ist operator[] schneller



  • k1ro schrieb:

    gibts dafür irgendwelche plausiblen gründe? (wills nur wissen, weil mich die aussage ziemlich verwundert)

    1. op[] ist logischer - wozu haben wir operator overloading?
    2. schreibst du
    for(int i=0; i<v.size(); ++i)
    {
      if(0<= i && i<v.size())
        cout<<v[i];
    }
    

    Das machst du hoffentlich nicht - wozu also doppelt checken lassen?
    3) die Exception die at wirft, verleitet viele zum unsauberen Programmieren. Ich habe schon öfters sowas gesehen:

    try
    {
      for(...)
      {
        do_something(v.at(i));
      }
    }
    catch(...)
    {}
    

    die exception wird einfach abgefangen und normal weiter gemacht - der code ist fehlerhaft, aber wir haben uns schön darum herum gedrückt ihn zu verbessern.



  • Noch nen tipp, wenn ihr einen Container wie vector durchläuft, macht folgendes:

    int size = vec.size (); // einmal Größe abfragen
    
    for (int i = 0; i < size; i++) // hier muss nicht jedesmal die größe erneut ermitteln werden
    

    Man kann die variable size natürlich auch in der Schleife initialisieren.



  • wie kann ich denn nun die Werte swappen?

    Tschau Gartenzwerg



  • SirLant schrieb:

    Noch nen tipp...

    ist das tatsächlich (getestet) schneller? denn ich wüsste keinen grund warum size() etwas anderes machen sollte als eine interne variable zurückliefern und das könnte der compiler ja wunderbar wegoptimieren.



  • japro schrieb:

    ist das tatsächlich (getestet) schneller? denn ich wüsste keinen grund warum size() etwas anderes machen sollte als eine interne variable zurückliefern und das könnte der compiler ja wunderbar wegoptimieren.

    Es _kann_ schneller sein. _muss_ aber nicht.

    Weil es eben auch sein kann - dass der Compiler sich nicht sicher ist, dass du den Container nicht veränderst.

    Es ist halt etwas, was nicht schadet wenn man es sich angewöhnt.

    Wobei ich eher iteratoren verwenden würde - das ist dann nämlich weniger Container abhängig.



  • ich nutze jetzt einen std::vector<int> statt einem std::vector<bool>. Dürfte sich vom Speicherbedarf ja nicht groß unterscheiden.

    Tschau Gartenzwerg



  • Der Unterschied sind 31Bits pro Wert.
    Wäre es nicht möglich, dass du dir ne eigene Swap Funktion schreibst? Müsstest ja nur zwei Iteratoren an deine Funktion übergeben, diese liest die Werte aus und macht den klassischen Dreieckstausch.



  • Shade of Mine schreibt:

    Hat vector<bool> denn ein at?

    btw: man verwendet at sowieso nicht - sondern man verwendet immer den operator[] - wir sind ja nicht bei Java

    😕

    Also darüber würde gern mal diskutieren.
    Wer Konstrukte wie

    try 
    { 
      for(...) 
      { 
        do_something(v.at(i)); 
      } 
    } 
    catch(...) 
    {}
    

    verwendet hat sowieso nichts besseres verdient als das er/sie ewig und drei Tage nach einen Indexüberlauf sucht. :p

    Ich selbst bevorzuge den Zugriff per .at überall da wo es nicht performance-kritisch ist. Und wer mir im Rahmen eines Funktionsaufruf mit nem ungültigen Index-Wert ankommt der kriegt vom mir die Orignal-Exceptiption um die Ohren gehauen, weil ich keine Lust habe die immer wieder gleiche Indexprüfung in den Code reinzuhämmern. 🙂

    mfg JJ



  • Weil ich mir noch nicht genug Feinde gemacht hab. 😉

    SriLant schriebt:

    Noch nen tipp, wenn ihr einen Container wie vector durchläuft, macht folgendes:

    int size = vec.size (); // einmal Größe abfragen
    for (int i = 0; i < size; i++) // hier muss nicht jedesmal die größe erneut ermitteln werden

    Was hälst du von der Verwendung von Iteratoren ? Warum ne Sonderabhandlung für Vektoren ? Weshalb nicht das gleiche Verfahren wie bei allen anderen STL-Containern ? 😕 😕

    mfg JJ



  • weil die vector Klasse auf sowas optimiert wurde? 😕



  • 31 Bit Unterschied? bool hat doch nicht nur 1 Bit oder?

    Tschau Gartenzwerg



  • bool kann nur 0/1 sein, also 1 bit



  • ich glaube, da irrst du. Auf meinem Linux sieht es wie folgt aus:

    sizeof(bool); // liefert 1 => 1 Byte
    sizeof(char); // liefert 1 => 1 Byte
    sizeof(int);  // liefert 4 => 4 Byte
    

    Kann sein, dass der vector<bool> auf ein Bit optimiert wurde!? Doch das normale bool hat min. 1 Byte. Vielleicht sollte ich dann anstatt vector<int> einen vector<char> nehmen.

    Tschau Gartenzwerg


Anmelden zum Antworten