Boost logo

Boost :

Subject: Re: [boost] [contract] concept error messages
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-10-07 15:51:05


On Sun, Oct 7, 2012 at 10:33 AM, Matt Calabrese <rivorus_at_[hidden]> wrote:
> On Sun, Oct 7, 2012 at 1:08 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]>wrote:
>
>> On Sat, Oct 6, 2012 at 5:06 PM, Matt Calabrese <rivorus_at_[hidden]> wrote:
>> > On Sat, Oct 6, 2012 at 2:29 PM, Andrew Sutton <asutton.list_at_[hidden]
>> >wrote:
>> >
>> >> Lots of reasons, but mostly it clearly delineates what is required
>> >> from what is returned.
>> >>
>> >
>> > I agree with you that requires is important, particularly for
>> concept-based
>> > overloads where one overload has more refined concepts than another
>>
>> Can you guys give me an example of this?
>
>
> std::advance, even in the C++98 standard library, is overloaded differently
> for input iterators than it is from bidirectional and random access
> iterators. With random access iterators, advance operates in constant time.
> With input iterators, advance operates linearly.

Sure, I understand:

template< class I, class Distance >
   requries InputIterator<I>
void advance( I& it, Distance n ) { /* linear complexity... */ }

template< class I, class Distance >
   requries BidirectionalIterator<I>
void advance( I& it, Distance n ) { /* ... */ }

template< class I, class Distance >
   requries RandomAccessIterator<I>
void advance( I& it, Distance n ) { /* constant complexity... */ }

I agree, this type of overloading is a reason for having requires,
enable_if will not suffice. Is there any other reason?

> The way this is currently
> implemented is via tag-dispatching -- on a call to std::advance, the
> iterator category is taken from iterator traits of the iterator argument
> and is used as an argument to a function with multiple overloads based on
> the iterator category that is passed (iterator_categories are related by
> inheritance, so even if you make an entirely new iterator category that is
> derived from the random access iterator category, the random access
> overload will still be picked). You can't simply emulate this behavior with
> enable_if by having a single enabler for random access iterators and a
> single enabler_for input iterators, etc. because a random access iterator
> IS an input iterator. The overload would be ambiguous. With a
> language-level concepts feature, you can get concept-based overloading to
> work entirely in the expected manner with no need for iterator categories,
> no need for tag dispatching, and the implementation works fine in the
> presence of user-provided concepts that refine standard iterator concepts.

Thanks,
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk