Boost logo

Boost Users :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-07-23 14:06:39


Raider wrote:
> Hi, i'm trying to modify rvalue container using Boost.ForEach:
>
> #include <string>
> #include <vector>
> #include <boost/foreach.hpp>
>
> typedef std::vector<std::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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net