|
Boost Users : |
From: Ian McCulloch (ianmcc_at_[hidden])
Date: 2005-03-04 15:43:19
[this is a repost - no idea what happened to the first version, maybe its
still floating around gmane somewhere - sorry in advance if this appears
twice]
Peter Dimov wrote:
> David Abrahams wrote:
>> "Peter Dimov" <pdimov_at_[hidden]> writes:
>>
>>> David Abrahams wrote:
>>>
>>>> ADL might not be the best customization solution.
>>>
>>> You keep saying that, but I keep disagreeing. ADL is the best
>>> customization solution. Not flawless, just better than any of the
>>> alternatives.
>>
>> I guess I haven't seen enough be definitively convinced one way or the
>> other. I have heard stories from people who switch to dispatching via
>> specialization and report how much better things get. Furthermore,
>> Daveed Vandevoorde has convinced me that it is far easier to reason
>> about. The rules for matching partial specializations are trivial
>> compared to the mess you have to consider when there is overloading.
>> The inconvenience of specialization is ugly, but it seems like a
>> one-time cost that may be justified for what it buys us.
>
> That's the thing. It doesn't actually buy us anything. It only claims to
> avoid potential problems.
I would disagree with that - it buys quite a lot, although for simple uses
the extra syntax might not be worth it.
>
> * Uglier syntax for defining a specialization.
IME, this is the biggest cost. I would include also the (one-off) cost of
providing a forwarding function to get a sane syntax for the outside world.
That is OK if you have a closed set of functions because the forwarding
function can be defined by the library, but if the library is merely
providing a framework for user-supplied algorithms it becomes a bit messy.
>
> * Coupling; you need to include a primary template.
Ok, but what does that primary template do? Surely nothing, or some very
conservative default.
>
> * Does not allow a base-specific version to be picked up automatically for
> derived classes.
But you can use a partial specialization heirachy instead. Something like
template <typename T>
struct forward_iterator {};
template <typename T>
struct bidirectional_iterator {};
// ...
typedef forward_iterator<void> forward_iterator_t;
typedef forward_iterator<bidirectional_iterator<void> >
bidirectional_iterator_t;
// ...
template <typename T, typename Tc = typename iterator_concept<T>::type>
struct my_algo_impl {};
template <typename T, typename Ti>
struct my_algo_impl<T, forward_iterator<Ti> >
{
// implement my_algo for forward iterators
};
template <typename T, typename Ti>
struct my_algo_impl<T, forward_iterator<bidirectional_iterator<Ti> > >
{
// implement my_algo for bidirectional iterators
};
Unfortunately, I don't know of a way of reducing the amount of typing needed
for overloads on a deep heirachy, other than macros.
>
> * Does not allow non-exact matches.
You could use enable_if<is_convertible<T,U> >. Of course that is asking for
trouble with ambiguous template specializations, but you would have a
similar problem using ADL, with ambiguous overloads. And its certainly
easier to control a set of template specializations verus an ADL overload
set.
>
> * If four libraries need the same operation, you need to specialize four
> primary templates.
Compare to four libraries using an ADL lookup on the same function name, but
requiring different semantics?
>
> In practice people tend to respect de-facto standards; a + b is an
> addition, and swap(a, b) swaps a and b. The main fight is over who gets to
> keep the primary template. But this is not really a problem with ADL
> customization points, because in their purest form, there is no primary
> template. The primary template is usually a compatibility workaround for
> types that do not support the ADL interface yet.
Sure, for de-facto standard operations, ADL works fine.
Cheers,
Ian
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