
From: "Jost, Andrew" <Andrew_Jost@mentor.com>
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Rob Stewart
From: "Jost, Andrew" <Andrew_Jost@mentor.com>
From: boost-bounces@lists.boost.org
{ T Def;
// METHOD #2b: use an adaptor-like predicate template< class T > class adaptor_substitute : public std::unary_function< boost::optional<T>, T 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?
Well, you called it a predicate at the top and I didn't really look that closely to see that it wasn't a predicate. I took your word for it and added confusion with my comment. The point I was trying to make was that you did, for all intents and purposes, write the adapter class.
// 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...
I'm sorry for your pain. ;)
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?
The real justification for your adapter idea is that the creator of the data doesn't know what default the consumer may need, or that there may be multiple consumers each with a different default. Thus, the producer uses a suitable sentinel value to indicate "no data" and the consumer uses an adapter to convert the sentinel value into a suitable default. A null pointer means no data, so the producer records null pointers and the consumer provides a default in lieu of null pointers. Likewise, NaN is an appropriate "no data" value, and the consumer uses an adapter to provide the desired default. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;