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
3002352B8
002352BC
002352C0
---
002352B8
002352B8
002352BC
002352C0
---
002352BC
002352B8
002352BC
002352C0
---
002352C0
002352B8
002352BC
002352C0
---
19
21
26Die 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::bindkopiert die Argumente. Woher soll die Funktion auch wissen, dass sie nur eine Referenz binden soll?
Du kannst hierboost::crefboost::refnehmen.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::refohne 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.