Почему back_inserter_iterator не является слабоинкрементируемым в RangeV3? - PullRequest
0 голосов
/ 13 июня 2019

К моему удивлению, это Концептуальное утверждение терпит неудачу в RangeV3.

#include<vector>
#include<range/v3/algorithm/copy.hpp>
int main(){
   static_assert(ranges::WeaklyIncrementable<std::back_insert_iterator<std::vector<double> >>());
}

Почему это так?

Это, среди прочего, означает, что я не могу использовать алгоритм ranges::copy, как я использую для 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.

Это канонический путь к back_insert в RangesV3?


Я не могу найти документацию WeaklyIncrementable в RangeV3, но в cppreference https://en.cppreference.com/w/cpp/experimental/ranges/iterator/WeaklyIncrementable кажется, что существует «другой тип со знаком», который, вероятно, не определен для back_inserter_iterator. Это, вероятно, означает 1 или 3 вещи, а) RangeV3 чрезмерно ограничивает требования copy б) copy не является алгоритмом обратной вставки, в) Я понятия не имею, как использовать RangeV3.


Нашел https://github.com/ericniebler/range-v3/issues/867, возможный обходной путь, чтобы использовать range::back_inserter(v) вместо std::back_inserter(v). Кажется, что где-то есть требование конструктивности по умолчанию.

1 Ответ

0 голосов
/ 13 июня 2019

Похоже, есть какие-то неожиданные (для меня) потребности в ranges::copy. Таким образом, RangesV3 предоставляет замену ranges::back_inserter, которая работает.

Однако в стандарте есть много других итераторов, которые не работают по той же причине, но для которых нет сбрасывания.в заменах, так что это может стать уродливым.

Например, мне пришлось адаптировать новый итератор для замены std::ostream_iterator, создавая некоторые искусственные функции, включая конструктор по умолчанию:

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;}
};

Сэто ranges::copy(first, last, ranges_ostream_iterator<int>(std::cout)) работает, тогда как ranges::copy(first, last, std::ostream_iterator<int>(std::cout)) не работает.

...