std::foreach-Verhalten (mit boost::bind) vs. BOOST_FOREACH-Verhalten mit Referenzen



  • Hallo zusammen,

    ich hatte heute eine etwas exotischere Situtation die vereinfacht so aussieht:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <boost/foreach.hpp>
    #include <boost/bind.hpp>
    
    void f( int& ri, std::vector<int>& vi )
    {
       std::cout << &ri << std::endl;
    
       BOOST_FOREACH( int &i, vi )
       {
          std::cout << &i << std::endl;
          i += ri;
       }
       std::cout << "---" << std::endl;
    }
    
    int main()
    {
       std::vector<int> vi;
       vi.push_back( 1 );
       vi.push_back( 2 );
       vi.push_back( 3 );
    
       std::cout << &vi[ 0 ] << std::endl;
       std::cout << &vi[ 1 ] << std::endl;
       std::cout << &vi[ 2 ] << std::endl;
       std::cout << "---" << std::endl;
    
       std::for_each( vi.begin(), vi.end(), boost::bind( f, _1, vi ) );
    
       BOOST_FOREACH( int &i, vi )
       {
          std::cout << i << std::endl;
       }
    
       std::cout << "==========================" << std::endl;
    
       std::vector<int> vi2;
       vi2.push_back( 1 );
       vi2.push_back( 2 );
       vi2.push_back( 3 );
    
       std::cout << &vi2[ 0 ] << std::endl;
       std::cout << &vi2[ 1 ] << std::endl;
       std::cout << &vi2[ 2 ] << std::endl;
       std::cout << "---" << std::endl;
    
       BOOST_FOREACH( int &i, vi2 )
       {
          f( i, vi2 );
       }
    
       BOOST_FOREACH( int &i, vi2 )
       {
          std::cout << i << std::endl;
       }
    }
    

    Die Ausgabe sieht so aus:

    002351A0
    002351A4
    002351A8
    ---
    002351A0
    00235230
    00235234
    00235238
    ---
    002351A4
    00235230
    00235234
    00235238
    ---
    002351A8
    00235230
    00235234
    00235238
    ---
    1
    2
    3

    002352B8
    002352BC
    002352C0
    ---
    002352B8
    002352B8
    002352BC
    002352C0
    ---
    002352BC
    002352B8
    002352BC
    002352C0
    ---
    002352C0
    002352B8
    002352BC
    002352C0
    ---
    19
    21
    26

    Die Variante mit BOOST_FOREACH() funktioniert wie erwartet, die Variante mit std::for_each scheint den std::vector zu kopieren (was ich halbwegs überraschend finde).
    Kann mir das einer erklären?
    Ich würde vermuten, dass es irgendetwas mit boost::bind und Referenzen auf Referenzen (bzw. der Vermeidung solcher) zu tun hat.



  • boost::bind kopiert die Argumente. Woher soll die Funktion auch wissen, dass sie nur eine Referenz binden soll?
    Du kannst hier boost::cref boost::ref nehmen.

    boost::bind(f, _1, boost::ref(vi))
    


  • Vielen Dank für die Antwort!

    Ich war davon ausgegangen, dass er automatisch eine & nimmt (die sollte dann aber eigentlich const sein... 🙄 und das würde auch wieder nicht funktionieren).

    Allerdings muss es in meinem Bsp. eine

    boost::ref
    

    ohne c sein, da über die Referenz modifiziert wird.



  • Mit C++11 gibt es eigentlich keinen Grund mehr, BOOST_FORAECH zu benutzen.



  • knivil schrieb:

    Mit C++11 gibt es eigentlich keinen Grund mehr, BOOST_FORAECH zu benutzen.

    Nur wird es noch eine Weile dauern, bis Range-Based-For soweit unterstützt wird, dass man damit portabel programmieren kann.



  • knivil schrieb:

    Mit C++11 gibt es eigentlich keinen Grund mehr, BOOST_FORAECH zu benutzen.

    Das ist richtig, aber ich hänge hier am VS2005 Compiler und deswegen ist nix mit C++11.


Log in to reply