
On Sun, Oct 7, 2012 at 10:33 AM, Matt Calabrese <rivorus@gmail.com> wrote:
On Sun, Oct 7, 2012 at 1:08 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Sat, Oct 6, 2012 at 5:06 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Sat, Oct 6, 2012 at 2:29 PM, Andrew Sutton <asutton.list@gmail.com 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