
I'm not quite sure I understand the behavior of this simple test of BOOST_FOREACH: ------------- #include <vector> #include <iostream> #include <boost/foreach.hpp> using namespace std; struct noisy_vector : public vector<int> { explicit noisy_vector(size_t const sz=0, int const val=0) : vector<int>(sz, val) { cerr << "\tcontainer was constructed" << endl; } noisy_vector(noisy_vector const& other) : vector<int>(other) { cerr << "\tcontainer was copied" << endl; } noisy_vector& operator=(noisy_vector const& other) { vector<int>::operator=(other); cerr << "\tcontainer was assigned" << endl; } ~noisy_vector() { cerr << "\tcontainer was destructed" << endl; } }; inline noisy_vector get_vec(size_t const sz, int const val=0) { return noisy_vector(sz,val); } int main() { cerr << "TEST 1: LVALUE" << endl; { noisy_vector vec = get_vec(5); cerr << "\tstarting foreach" << endl; BOOST_FOREACH(int const& i, vec); } cerr << endl; cerr << "TEST2: LVALUE, REFERENCE" << endl; { noisy_vector const& vec = get_vec(5); cerr << "\tstarting foreach" << endl; BOOST_FOREACH(int const& i, vec); } cerr << "TEST 2: RVALUE" << endl; { cerr << "\tstarting foreach" << endl; BOOST_FOREACH(int const& i, get_vec(5)); } } ------------- If I compile this, using g++ 3.4.4, with the RVO disabled (using -fno-elide-constructors), then I get the following output: ------------- TEST 1: LVALUE container was constructed container was copied container was destructed container was copied container was destructed starting foreach container was destructed TEST2: LVALUE, REFERENCE container was constructed container was copied container was destructed starting foreach container was destructed TEST 2: RVALUE starting foreach container was constructed container was copied container was destructed container was copied container was copied container was destructed container was destructed container was destructed ------------- If I compile it with the RVO enabled, I get the following output: ------------- TEST 1: LVALUE container was constructed starting foreach container was destructed TEST2: LVALUE, REFERENCE container was constructed starting foreach container was destructed TEST 2: RVALUE starting foreach container was constructed container was copied container was destructed container was destructed ------------- So in either case, using BOOST_FOREACH requires one extra copy. Why is this necessary? I guess the macro is making a copy of the argument to avoid evaluating it more than once, but isn't it possible just to bind the temporary to a const reference instead? Thanks... -Lewis