|
Boost : |
From: Jost, Andrew (Andrew_Jost_at_[hidden])
Date: 2005-07-20 05:14:36
> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Rob Stewart
> From: "Jost, Andrew" <Andrew_Jost_at_[hidden]>
> > From: boost-bounces_at_[hidden]
<clip>
> > example code (BTW, others seem to prefer the spelling
> "adaptor," which
> > is more consistent with other standardized names like
> "iterator," so
> > I'll conform to that):
>
> I took a look at "adapter" and "adaptor" at dictionary.com.
> Most dictionaries list "adapter" as the main entry and
> "adaptor" as a variant. WordNet at Princeton University
> makes the two synonymous only for this usage.
>
> A quick Google search showed 18.2 million hits for "adapter" and
> 4.1 million for "adaptor."
>
> I think "adapter" is the right spelling in this case.
>
I also checked dictionary.com and came to the same initial conclusion,
but so many people used "adaptor" in their replies that it made me
wonder whether that spelling was more appropriate. I prefer whichever
spelling is intuitive for most users.
<clip>
>
> > // METHOD #2a: define a custom predicate template< class T, class
> > Pred, T Def = T() > class optPred : public
> > std::binary_function<boost::optional<T>,
> > boost::optional<T>, bool> {
> > Pred f;
> > T _eval( const boost::optional<T>& x ) const {
> > return ( x ? x.get() : Def );
> > }
> > public:
> > optPred() : f( Pred() ) {}
> > bool operator()( const first_argument_type& a, const
> > second_argument_type& b ) const {
> > return f( _eval(a), _eval(b) );
> > }
> > };
> > opt_int opt_max;
> > opt_max= *std::max_element( v.begin(), v.end(), optPred< int,
> > std::less<int>, -1 >() );
>
> That's a lot of work. You'd want to use something like
> Boost.Lambda to make this more reasonable.
>
Yes, way too much work. See below.
> > // METHOD #2b: use an adaptor-like predicate template<
> class T > class
> > adaptor_substitute : public std::unary_function<
> boost::optional<T>, T
> > > {
> > T Def;
> > public:
> > _adaptor_() : Def( T() ) {}
> > _adaptor_(T def) : Def( def ) {}
> > T operator()(const argument_type& x ) {
> > return ( x ? x.get() : Def );
> > }
> > };
> > max = *std::max_element(
> > boost::make_transform_iterator( v.begin,
> > adaptor_substitute<int>(-1) ),
> > boost::make_transform_iterator( v.end,
> adaptor_substitute<int>(-1)
> > )
> > );
>
> This isn't really an adapter substitute. It is an adapter,
> adapted (pun intended) to be a predicate.
>
But a predicate must return bool, not T. Did I miss something?
> > // METHOD #3: use an adaptor
> > max = *std::max_element(
> > boost::make_transform_iterator( v.begin,
> > boost::optional<int>::adaptor(-1) ), // NOTE:
> > boost::optional<int>::adaptor does not currently exist
> > boost::make_transform_iterator( v.end,
> > boost::optional<int>::adaptor(-1) )
> > );
>
> That is clearly the most straightforward of the bunch, but
> I'd like to see a proper Boost.Lambda or Boost.Function
> variant for comparison.
>
I would prefer to use Boost.Lambda, but I am currently stuck on VC6 for
Win32 development. It is becoming a problem...
> BTW, why have you shown the adapter as a nested type of
> boost::optional? Do you not think it is applicable to
> anything else? I can envision adapting pointers or even
> floating point types (where NaN is the "empty" value), to
> name just two more types adapter might support.
I guess I started with Boost.Optional in mind and never considered
anything else. Also, depending on the implementation the adapter may
need to interact with Boost.Optional. Can you provide examples of some
ways you might use an adapted pointer or float?
-Andy
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk