Reputation: 4545
I am wondering if there is any benefit to getting a reference to a vector prior to calling BOOST_FOREACH or whether a method call which returns a reference will be automatically used? For example which of the two following loops will be equivalent to the third loop?
vector<float>& my_method();
void main()
{
// LOOP 1 -------------------------------
vector<float>& temp_vector = my_method();
BOOST_FOREACH(float element, temp_vector)
cout << element << endl;
// LOOP 2 -------------------------------
vector<float> temp_vector = my_method();
BOOST_FOREACH(float element, temp_vector)
cout << element << endl;
// Which loop is this one most like? ----
BOOST_FOREACH(float element, my_method())
cout << element << endl;
}
Upvotes: 3
Views: 2394
Reputation: 84972
Looking through BOOST_FOREACH
metaprogramming madness I see that the collection gets copied if it's
boost::foreach::is_lightweight_proxy
.Hence, lvalue is not copied. Instead, its pointer is taken as a temporary.
Crucial bit is this:
# define BOOST_FOREACH_SHOULD_COPY(COL) \
(true ? 0 : boost::foreach_detail_::or_( \
BOOST_FOREACH_IS_RVALUE(COL) \
, BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL)))
Then it's used as one of the arguments to the function that is used to evaluate a container into a temporary variable:
template<typename T>
inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue
{
return t;
}
template<typename T>
inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue
{
// Cannot seem to get sunpro to handle addressof() with array types.
#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570))
return &t;
#else
return boost::addressof(t);
#endif
}
I have Boost v1.38 installed in my system.
Upvotes: 2
Reputation: 8834
A quick test shows that the function is called once and no copying occurs in connection with BOOST_FOREACH
.
#include <vector>
#include <iostream>
#include <boost/foreach.hpp>
struct X
{
X() {}
X(const X& ) { std::cout << "copied\n"; }
};
std::vector<X> vec(2);
//std::vector<X> method()
std::vector<X>& method()
{
std::cout << "returning from method\n";
return vec;
}
int main()
{
BOOST_FOREACH(const X& x, method()) {}
}
Upvotes: 4
Reputation: 3852
so my_method()
won't be called more than once
References behaves like "normal" variables from the user point of view, you can treat the reference exactly as if it were the original variable. It makes no difference to the foreach loop.
So both loops are equivalent.
Upvotes: 0