Raider wrote:
Hi, i'm trying to modify rvalue container using Boost.ForEach:
#include <string> #include <vector> #include
typedef std::vectorstd::string vec;
inline boost::mpl::true_ * boost_foreach_is_lightweight_proxy(vec *&, boost::foreach::tag) { return 0; }
vec GetVector() { vec v; v.push_back("hello"); v.push_back("world"); return v; }
int main() { // compiles ok GetVector().push_back("oh god, it's writable!");
// next line gives "unable to convert `const string' to `string&'" BOOST_FOREACH(std::string& String, GetVector()) String.clear();
return 0; }
It doen't compiles (MCVC 8.0) - it looks like boost_foreach_is_lightweight_proxy is ignored. What's wrong?
It's not being ignored --- std::vector is simply not a lightweight proxy. You're lying to BOOST_FOREACH, and it's found you out. :-) The docs say this about lightweight proxy types:
A pair of iterators is an example of a lightweight proxy. It does not store the values of the sequence; rather, it stores iterators to them. This means that iterating over a copy of the proxy object will give the same results as using the object itself.
Iterating over a copy of a std::vector isn't the same thing as as iterating over the original vector because the elements have been copied. When BOOST_FOREACH has to make a copy of a sequence (and it always copies lightweight proxies), it treats the copy as const because it's a temporary object. That's fine for *real* proxies because the const-ness of the proxy doesn't affect the constness of the referred-to elements. I think BOOST_FOREACH is doing the right thing here. -- Eric Niebler Boost Consulting www.boost-consulting.com The Astoria Seminar ==> http://www.astoriaseminar.com