
On 8/13/07, David Abrahams <dave@boost-consulting.com> wrote:
on Mon Aug 13 2007, "Martin Schulz" <Martin.Schulz-AT-synopsys.com> wrote:
Giovanni, sorry for the late reply.
Consider this:
std::vector<int> x = .... for_each(filter(x, some_filter_op), do_something);
'Filter' will obviously return a proxy for 'x' (actually wrapping x iterators with boost::filter iterators) as a temporary object. for_each will bind the temporary to a const reference (at least until we get rvalue references).
The fact that temporary objects cannot be passed in as non-const references had been decided to avoid programming accidents in that modifications to the temporary object were assumed to be meaningfull and should be preserved. If you want this object as non-const nevertheless, simply give a name to it.
That's less simple than you make it sound. It could have a very complicated type.
Yep, exactly. And when you throw boost.lambda in, your objects have types you do not even want to look at.
One good way to deal with this is to make the proxy object return a constant object. Then it will bind to a T& parameter.
That was what I did at the beginning, but I had to deal with lots of third party functions that didn't constify their arguments, so I ended up writing a forwarding layer that provides all const/non-const overloads up to 5 arguments (I could have used the one provided by fusion, but I'm stuck with boost 1.32, so I have to reinvent the wheel over and over). All my range functions are actually function objects (for bind compatibility) so this works very well.
Furthermore, the constness of the proxy should not affect the constness of its access to elements of x. That essentially means returning a different proxy type depending on whether the incoming container is const or not.
Agree 100%. gpd