Boost logo

Ublas :

From: Michael Stevens (mail_at_[hidden])
Date: 2005-09-01 11:53:34

On Donnerstag 25 August 2005 20:06, Ian McCulloch wrote:
> >
> > This is a fundamental problem with the current implementation of uBLAS
> > proxies. They propagate (as a normal object would) this constantness to
> > their operations. This is advantageous in that it is consistent with
> > other objects and provides error messages at a relatively high level in
> > the instaneation hierarchy.
> >

> >
> > It would be interesting to here how other libraries deal with the problem
> > of closures as temporary return values. MTL3, GLAS anyone?
> I get around it with a hack: a metafunction is_mutable_proxy<T> that
> returns mpl::true_ iff T is a non-const proxy (or reference) to a non-const
> (in this scheme I regard 'proxy<U const>' and 'const proxy<U>' as
> equivalent, so is_mutable_proxy<T const> is always false_). Then

Ian, thanks for the info. This gives me some idea how this could be worked
around with something similar.

> template <typename T>
> void
> some_function(T& x) { ... }
> template <typename T>
> inline
> typename boost::enable_if<is_proxy_reference<T> >::type
> some_function(T const& x)
> {
> some_function(const_cast<T&>(x));
> }
> I am optimistic that rvalue references will eventually make it into C++,
> then the hackery will go away and it will simply be
> template <typename T>
> void
> some_function(T&& x) { ... }
That would solve the problem :-)

> Not sure if it is a good idea for uBLAS to go down this route, it uses a
> lot of SFINAE and a whole suite of metafunctions to keep track of const
> correctness (and even then it is only approximately const-correct, because
> of the const_cast hack).

I agree, the road is too bumpy!!

uBLAS previously had an always enable const_cast hack in the project
functions. This allowed the 'project' functions to work on temporaries. Had
the nasty side effect that it allowed 'undefined' behaviour is the projected
object was indeed constant.

> A simpler way might be to ignore the top-level const and simply have
> proxy<T> and proxy<T const>. Then the const_cast hack above is actually
> correct ;) But then it is not possible convert a non-const proxy into a
> const-proxy. Maybe that doesn't matter much for uBLAS? For me it wasn't
> really an option, as many of my container classes are copy-on-write
> reference counted.

I looked something similar. Specialising the way that closure and reference
types in uBLAS expressions are propagated for proxies. Effectively this would
allow non-const access to const proxies if the final closed on object was
This would have meant that these const proxy objects were logically non
constant. Semantically this becomes a nightmare! The implementation required
extensive 'mpl::if' logic which was also costly. I gave up in the end!