Boost logo

Boost Users :

From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2007-01-23 12:05:19


On 1/23/07, Joaquín Mª López Muñoz <joaquin_at_[hidden]> wrote:
>
> it might be a good idea to provide an additional
> predefined
> key extractor for use with free functions so as to supplement the existing
>
> ones working with member functions, I'll add this to my to consider list.
>
> Hope this helps,
>
> Joaquín M López Muñoz
> Telefónica, Investigación y Desarrollo

I'm currently experimenting with a rule of thumb where my extensible
template classes are all written using policies, but the default for each
policy is one that calls a free function. Sort of a best of both worlds
approach - or at least that's what I'm hoping. For example, intrusive_ptr
could be rewritten to take an AddRef policy, and the default could be to
call intrusive_ptr_add_ref, etc:

template <typename T>
struct intrusive_ptr_default_add_ref_policy
{
   static void add_ref(T * t)
   {
      intrusive_ptr_add_ref(t);
   }
};

template <typename T, typename AddRefPolicy =
intrusive_ptr_default_add_ref_policy>
struct intrusive_ptr
{
   intrusive_ptr(...)
   {
      ...
      AddRefPolicy::add_ref(t);
   }
};

So user can implement intrusive_ptr_add_ref() OR implement a policy class.

Might not be worthwhile for intrusive_ptr but it's an easy example.
Probably makes more sense for templates where you might actually want
different behaviours for a particular type, in different contexts. Much
like passing in a predicate to std::map<>, yet the default is std::less,
which is based on the type's intrinsic operator<().

Speaking of map<> and std::less(), I kind of wish they added one extra point
of abstraction there - something like std::order() or map_order() or
key_order(), that was allowed to be overridden. The idea being that some
types can have a meaningful order() when used as a key, that is different
than the meaningful operator<(). In my case it was a string class
consisting of shared static strings - so that, used as a key, they could be
quickly compared using the actual pointer to the shared memory, so
operator<() would be implemented using that method; but used as a typical
string, you might want to order them aphabetically, so operator<() should be
a lexigraphical compare. And yes, I could just make sure my map<> took a
custom predicate, but I'd rather the string class control that 'intrinsic',
and not have to police future uses of the class when used as a key, to
ensure the right predicate is used.
The real answer probably is that std::map<> should call a free function,
like, say, extract_key(T const & t), and then call the predicate on that,
instead of on T.
Hey, which gets us right back to where we started - multi-index DOES have
key-extraction (making it better than std::map<> already), and the OP is
asking for it to be a free function! Now if we could only get std::map<> to
use it...

Tony



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net