To my surprise this Concept-like assertion fails in RangeV3.
#include<vector>
#include<range/v3/algorithm/copy.hpp>
int main(){
   static_assert(ranges::WeaklyIncrementable<std::back_insert_iterator<std::vector<double> >>());
}
Why is that?
This, among other things means that I cannot use the ranges::copy algorithm as I use to do with std::copy. 
    std::vector<double> w(100);
    std::vector<double> v;
    ranges::copy(
        begin(w), end(w),
        std:back_inserter(v)
    );  // compilation error, concept not fulfilled.
Is this the canonical way to back_insert in RangesV3?
I cannot find the WeaklyIncrementable documentation in RangeV3, but in cppreference https://en.cppreference.com/w/cpp/experimental/ranges/iterator/WeaklyIncrementable it seems that there is a "signed different type" that is probably not defined for back_inserter_iterator. This probably means 1 or 3 things, a) RangeV3 is overconstraining the copy requirements b) copy is not the algorithm for back insertion, c) I have no clue how to use RangeV3.
Found this https://github.com/ericniebler/range-v3/issues/867, a possible workaround it to use range::back_inserter(v) instead of std::back_inserter(v). It seems that there is a default constructibility requirement somewhere.
It looks like there are some unexpected (to me) requirements need by ranges::copy. So RangesV3 provides a drop in replacement ranges::back_inserter that works.
However there are many other iterators in the standard that do not work for the same reason but to which there is no drop-in replacements, so it can get ugly.
For example, I had to adapt a new iterator to replace std::ostream_iterator creating some artificial functions, including a default constructor:
template<class T>
struct ranges_ostream_iterator : std::ostream_iterator<T>{
    using std::ostream_iterator<T>::ostream_iterator;
    ranges_ostream_iterator() : std::ostream_iterator<T>{std::cout}{} // I have to put something here
    ranges_ostream_iterator& operator++(){std::ostream_iterator<T>::operator++(); return *this;}
    ranges_ostream_iterator& operator++(int){return operator++();}      
    using difference_type = int;
    int operator-(ranges_ostream_iterator const&){return 0;}
};
With this, ranges::copy(first, last, ranges_ostream_iterator<int>(std::cout)) work, whereas ranges::copy(first, last, std::ostream_iterator<int>(std::cout)) doesn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With