Hacker News new | ask | show | jobs
by cschwan 4291 days ago
How would concepts simplify this?
1 comments

Using unqualified templates, the compiler can't distinguish between

template<typename RANGE, typename PRED> void sort(RANGE, PRED);

and

template<typename ITERATOR> void sort(ITERATOR start, ITERATOR stop);

Since we already have the iterator algorithm defined, there is no room for a range algorithm name 'sort' with two template-deduced parameters. There are workarounds using enable_if, but they're hairy and involve basically recreating concepts at the standard library level.

Herb Sutter:

"I’m hopeful that the standard library will get range-based overloads of all standard algorithms that are enable_if’d to avoid the problem or can use concepts if those make it into a future standard."

http://herbsutter.com/2011/10/07/why-no-container-based-algo...

Why concepts then? The concepts version would look like:

template<Range, Comparator> void sort(Range & r, Comparator const & c);

...and the compiler would be able to tell that iterators wouldn't work with this algorithm.

Actually, the compiler can distinguish between sort(Range, Pred) and sort(Iter, Iter). This is a C++98 feature, partial ordering of function templates. Basically, if you call sort(range, pred) then the sort(Iter, Iter) overload will be ignored (since template argument deduction can't succeed - Iter can't be two different types). If you call sort(iter1, iter2) then both overloads are viable, but sort(Iter, Iter) is preferred - partial ordering determines that it matches a strictly smaller infinite universe of types.

This is also why C++14's dual-range algorithms didn't lead to ambiguities: equal(InIt1, InIt1, InIt2, Pred) versus equal(InIt1, InIt1, InIt2, InIt2) has the same structure.

(Obviously if you have a type that is both a range and a predicate, then it's ambiguous.)