|
Boost : |
From: Levente Farkas (lfarkas_at_[hidden])
Date: 2001-10-05 05:34:36
hi,
so the real problem are deeper. I try to explain it more precisely.
AdaptableUnaryFunction has tt typedef argument_type and result_type.
As Peter Dimov pointed out the bind library doesn't attempt to lie
about this type. BUT the whole C++ standard do so!!!
let's look at the definition of the functors in <functional>
(this's a quote from the final c++ standard):
--------------------
template <class T> struct plus : binary_function<T,T,T> {
T operator()(const T& x, const T& y) const;
};
--------------------
while argument_type is T the real arguments are const T&. so here comes
the basic of the problems. what's happend if some new class/functor/operator
relies on F::argument_type and try to something like const F::argument_type&
is ok, but if it use F::argument_type it's no longer a reference rather a
local COPY of the original value so can't made further reference. so if we
use boost::bind which doesn't lie than it can't be used with anything from
<functional>.
let's see the other part what happens if we define plus as:
--------------------
template <class T> struct plus : binary_function<T,const T&,const T&> {
T operator()(const T& x, const T& y) const;
};
--------------------
which IMHO would be a better choise, but in this case we have to change
the standard. if someone suppose from a functor's F::argument_type as
a value_type than try to give it further const F::argument_type& this's
a reference ot a reference problem. the same story for result_type
also implies mainly when we try to put together to functors like bind
like to do.
here come the projection_iterator. what would have to suppose
projection_iterator about it's selector's result_type. it's a real
result_type sometimes T sometimes T& or it's always the base T type.
I said again. I don't know the solution. I just run into this problem
and it's took me a while in a hard way to find out the problem.
David Abrahams wrote:
>
> Sorry, Levente, I can't make head or tail of your mail.
>
> If you don't have a real lvalue lying around which you can reference, you
> can't use projection_iterator_adaptor.
the real return type is a reference, BUT F::result_type (as I explain
above) it NOT a reference (and of cource it can't be an lvalue).
> Is this the problem?
>
> AdaptableUnaryFunction: The type of the function object. The argument_type
> of the function must match the value type of the base iterator. The function
no IMHO match is not enough it should have be the same! eg. T match T&
but T cant be derefered later:-(
> should return a reference to the function's result_type. The result_type
> will be the resulting iterator's value_type.
>
> Is the result_type of an AdaptableUnaryFunction returning a reference
> supposed to be a reference type? I would think so. Our documentation seems
> to suggest making the result_type a value instead. Jeremy?
>
> ===================================================
> David Abrahams, C++ library designer for hire
> resume: http://users.rcn.com/abrahams/resume.html
>
> C++ Booster (http://www.boost.org)
> email: david.abrahams_at_[hidden]
> ===================================================
>
> ----- Original Message -----
> From: "Levente Farkas" <lfarkas_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Thursday, October 04, 2001 2:44 PM
> Subject: Re: [boost] more problem with functional + projection_iterator
>
> > yes. ok it's a stupid example, but I don't want to make it more
> compilcated.
> > suppose I have a function which smooth an iterator range than change the
> > copy to smooth, that my iterator has to return a reference not a value:
> > --------------------------
> > smooth(
> > boost::make_const_projection_iterator(a.begin(),
> > boost::compose1(VectorAccess<std::vector<double> >(0),
> > MemberAccess<A, std::vector<double> >(&A::y))),
> > boost::make_const_projection_iterator(a.end(),
> > boost::compose1(VectorAccess<std::vector<double> >(0),
> > MemberAccess<A, std::vector<double> >(&A::y))),
> > boost::make_const_projection_iterator(a.begin(),
> > boost::compose1(VectorAccess<std::vector<double> >(0),
> > MemberAccess<A, std::vector<double> >(&A::y))));
> > --------------------------
> >
> >
> > David Abrahams wrote:
> > >
> > > Are you sure you don't want a transform_iterator_adaptor instead?
> > >
> > > -Dave
> > >
> > > ===================================================
> > > David Abrahams, C++ library designer for hire
> > > resume: http://users.rcn.com/abrahams/resume.html
> > >
> > > C++ Booster (http://www.boost.org)
> > > email: david.abrahams_at_[hidden]
> > > ===================================================
> > >
> > > ----- Original Message -----
> > > From: "Levente Farkas" <lfarkas_at_[hidden]>
> > > To: "boost" <boost_at_[hidden]>
> > > Sent: Thursday, October 04, 2001 12:25 PM
> > > Subject: [boost] more problem with functional + projection_iterator
> > >
> > > > hi,
> > > > I try to compile the attached example and faild both with MSVC 6sp5
> and
> > > > gcc-2.96 on linux. the problem is in unary_compose (from compose1).
> even
> > > if I
> > > > switch from std::compose1 to boost::compose1 the problem exists. the
> > > reason
> > > > is a bit complicated. every function object (subclass of
> > > std::unary_function)
> > > > return with result_type which is usualy not a reference! what's more
> it
> > > > can't be a reference since everybody suppose these functions are
> return
> > > > with T& and result_type defined as T. that's the reason why
> > > projection_iterator
> > > > suppose it and put & the place where it's required. IMHO this whole
> > > > thing is a huge design mistake. result_type should have to be defined
> > > > as the real result type of operator(). anyway this would be a better
> > > > choise for argument_type too. solutions (if we don't would like to
> > > > change the whole stl paradigm to right way result_type have to be the
> > > > real result type,...) to change all functionals definition to
> > > > typename call_traits<typename
> > > unary_traits<Operation1>::result_type>::param_type
> > > > in this case all functor can be used as an argumnet for another
> functor.
> > > > without this this's unsolvable.
> > > > or anybody has any better idea?
-- Levente "Si vis pacem para bellum!"
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk