iterator als Referenz? Und const oder const_iterator?



  • Blume schrieb:

    Aber per Referenz wäre ja doch schneller als per Kopie, nicht?

    Ähm, neee.
    Nehmen wir mal einen vector<int>::iterator

    struct iterator
    {
      int* data;
      iterator& operator++(){
         ++data;
      }
      operator*(){
        return *data;
      }
      friend bool operator!=(iterator a,iterator b){
        return a.data!=b.data;
      }
      ...
    }
    

    oder einen
    list<int>::iterator

    struct iterator
    {
      list<int>::node* data;
      iterator& operator++(){
         data=data->next;
      }
      operator*(){
        return data->value;
      }
      friend bool operator!=(iterator a,iterator b){
        return a.data!=b.data;
      }
      ...
    }
    

    die haben beie nur 4 bytes größe. kopieren ist da eine ganz nette idee.



  • Hmm, bei mir sizeof(vector<int>::iterator) = 12.



  • Blume schrieb:

    Hmm, bei mir sizeof(vector<int>::iterator) = 12.

    mach mal die debug-prüfungen aus.



  • Äh, sorry, wenig Ahnung.
    Im Release-Build sind es noch 8 Bytes.

    Dann habe ich noch "Debug Information Format" auf "Disabled" und "Generate Debug Info" auf "No" gestellt (Visual Studio 2008), etwas anderes hab ich nicht gefunden.



  • Und warum kostet eine Referenz eigentlich mehr/gleich viel wie eine Kopie, oder warum überhaupt etwas?
    Könnte doch vom Compiler völlig wegoptimiert werden, nicht?
    Geht ja im C++ Code nur um die Sichtbarkeit der Variable, also dass ein Zugriff dort stattfindet, wo die Variable nicht bekannt ist.



  • Blume schrieb:

    Und warum kostet eine Referenz eigentlich mehr/gleich viel wie eine Kopie, oder warum überhaupt etwas?
    Könnte doch vom Compiler völlig wegoptimiert werden, nicht?
    Geht ja im C++ Code nur um die Sichtbarkeit der Variable, also dass ein Zugriff dort stattfindet, wo die Variable nicht bekannt ist.

    Referenzen können nicht immer wegoptimiert werden, z.B. wenn sie viel herumgereicht werden. Meistens sind sie intern nicht viel anderes als Zeiger.


  • Mod

    Blume schrieb:

    Ich möchte ein Element eines Containers an eine Funktion übergeben.

    Wenn es nur ein Element ist, übergib nur dieses eine Element per Referenz oder Kopie - in diesem Falle ist es völlig irrelevant, ob das Element in einem Container steckt oder nicht und es gibt keinen Grund, den Aufrufer hier zu irgendetwas zu zwingen.

    Soll mehrere Elemente als Teil einer Sequenz übergeben werden, wirst du ohnehin eine Kopie des Iterators benötigen, um über diese Elemente zu iterieren, dann kann die Kopie genauso gut gleich beim Funktionsaufruf gemacht werden - das ist zudem effizienter, weil wir dabei ggf. von RVO profitieren können.



  • Blume schrieb:

    Äh, sorry, wenig Ahnung.
    Im Release-Build sind es noch 8 Bytes.

    Dann habe ich noch "Debug Information Format" auf "Disabled" und "Generate Debug Info" auf "No" gestellt (Visual Studio 2008), etwas anderes hab ich nicht gefunden.

    Verstehe ich nicht. Wozu nimmt der zwei Zeiger statt einem?


  • Mod

    volkard schrieb:

    Blume schrieb:

    Äh, sorry, wenig Ahnung.
    Im Release-Build sind es noch 8 Bytes.

    Dann habe ich noch "Debug Information Format" auf "Disabled" und "Generate Debug Info" auf "No" gestellt (Visual Studio 2008), etwas anderes hab ich nicht gefunden.

    Verstehe ich nicht. Wozu nimmt der zwei Zeiger statt einem?

    Weil es ein checked iterator ist. Es fehlt noch ein

    #define _SECURE_SCL 0
    

    zweckmäßigerweise macht man das über die Projekteinstellungen, also zusätzlich _SECURE_SCL=0 bei den Präprozessorsymbolen.



  • Oh.. ja, stimmt.
    In meinem Fall benötige ich es eh nur, um in der Funktion über den Iterator auf die Methoden des Objekts zuzugreifen.
    Dann werde ich also beim Aufruf den Iterator dereferenzieren und als Parameter der Funktion kommt ein "const ClassType& classType" hin.

    Danke nochmals.
    MfG


Anmelden zum Antworten