Raider wrote:
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.
It's not about std::vector, it's about boost_foreach_is_lightweight_proxy. I used std::vector only to make example code small. If you think std::vector make sence, you can change "typedef std::vectorstd::string vec;" line by the following:
typedef vector<string> sv; sv global; class vec { public: vec(sv& v = global) : v_(v) {} typedef sv::iterator iterator; typedef sv::const_iterator const_iterator; iterator begin() { return v_.begin(); } iterator end() { return v_.end(); } const_iterator begin() const { return v_.begin(); } const_iterator end() const { return v_.end(); } void push_back(const string& s) { v_.push_back(s); } private: sv& v_; };
It's a *real* _lightweight_ proxy, but still getting a compiler error!
Better, but you have proxied a non-const vector, and you're presenting a const interface. Try this: class vec { public: vec(sv& v = global) : v_(v) {} typedef sv::iterator iterator; typedef sv::iterator const_iterator; typedef sv::const_iterator const_iterator; iterator begin() const { return v_.begin(); } iterator end() const { return v_.end(); } void push_back(const string& s) const { v_.push_back(s); } private: sv& v_; }; The const-ness of the proxy itself shouldn't matter. Only the const-ness of the proxied object should matter. HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com The Astoria Seminar ==> http://www.astoriaseminar.com