
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. 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. -- -Matt Calabrese