|
Boost : |
Subject: Re: [boost] [concept] concept-based overloading (N2081)
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-05-27 16:59:20
On 5/27/2010 12:57 PM, Lorenzo Caminiti wrote:
> On Thu, May 27, 2010 at 1:48 PM, Jeffrey Lee Hellrung, Jr.
> <jhellrung_at_[hidden]> wrote:
>> On 5/27/2010 10:38 AM, Lorenzo Caminiti wrote:
>>> N2081 briefly mentions this can be done in C++ using SFINAE, etc. I
>>> think I could use `enable_if` if I had some sort of
>>> `is_input_iterator` metafunction... Please just point me to the
>>> documentation if this has already been addressed there.
>>>
>> Do you mean the iterator_category / iterator_traversal metafunctions in
>> boost/iterator/iterator_traits.hpp ?
[...]
>>
>> http://www.boost.org/libs/iterator/doc/iterator_traits.html
>>
>> template< class Iterator>
>> typename boost::disable_if<
>> boost::is_convertible<
>> typename boost::iterator_traversal< Iterator>::type,
>> boost::bidirectional_traversal_tag
>> >
>>> ::type
>> advance(...) { ... } // for IncrementableIterator's
>>
>> template< class Iterator>
>> typename boost::enable_if<
>> boost::is_convertible<
>> typename boost::iterator_traversal< Iterator>::type,
>> boost::bidirectional_traversal_tag
>> >
>>> ::type
>> advance(...) { ... } // for BidirectionalIterator's
>>
>> I think the primary way to currently effect "concept-based" overloading is
>> via tags or similar metafunction-based methods. There do exist
>> introspection techniques, though, such as proto's can_be_called or
>> is_incrementable in boost/detail/, so it is possible to overload based on
>> (some) syntactic properties.
>>
>> Is that what you're looking for?
>
> Essentially, the above code from Jeff got the job done for what I
> needed. I used `enabled_if` and tagging.
>
> Also thanks to everyone else for the very informative comments.
>
Just so an "inferior" approach isn't mistaken as the "correct" solution,
Thomas is right, you should use tag-dispatching if possible:
template< class Iterator >
void advance_dispatch(..., boost::incrementable_traversal_tag) { ... }
template< class Iterator >
void advance_dispatch( ..., boost::bidirectional_traversal_tag) { ... }
template< class Iterator >
void advance(...)
{ advance_dispatch(..., typename iterator_traversal< Iterator >::type()); }
And now that I've written this, I see this exact example is already
elaborated on at the boost website:
http://www.boost.org/community/generic_programming.html#tag_dispatching
Sorry for any misdirection,
- Jeff
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk