Hacker News new | ask | show | jobs
by cschwan 4291 days ago
"Relaxed requirements for constexpr" is an item that I wish would have gone into C++11. Once have you multiple code paths and need to loop over variables constexpr functions get really unreadable.

One thing the C++ standard library IMO needs is a range library, e.g. something like Boost Range. I often would like to use the "range-for" but when I am not looping over all the elements of a container its useless in that case.

3 comments

Eric Neibler is working on bring a range library into the standard. His blog is a good source of info on his approach: http://ericniebler.com/
Thanks for the pointer!
constexpr was already difficult to implement (much more difficult than originally thought). As far as I understand, the committee wanted to be conservative in scope in case a limited constexpr could serve the needed use cases without being an limitless source of compiler complexity and bugs.

I agree about the range library, but it will be difficult to impossible to implement in the standard library without concepts. 2020 could be the year of range algorithms.

How would concepts simplify this?
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.)