Я пытаюсь преобразовать свой диапазон (пара итераторов) в iterator_range
, чтобы я мог использовать все представления и действия. Я могу преобразовать свой диапазон в boost::iterator_range, но получаю ошибку компиляции при преобразовании в range::v3. Вот минимальный пример:
struct MyRange
{
struct iterator_t : std::iterator<std::input_iterator_tag, int>
{
friend bool operator==(const iterator_t& lhs, const iterator_t& rhs);
friend bool operator!=(const iterator_t& lhs, const iterator_t& rhs);
};
iterator_t begin() { return iterator_t{}; };
iterator_t end() { return iterator_t{}; };
};
int main(int argc, char *argv[])
{
auto my_range = MyRange{};
auto boost_range = boost::make_iterator_range(my_range.begin(), my_range.end()); // works
auto v3_range = ranges::v3::make_iterator_range(my_range.begin(), my_range.end()); // doesn't compile
}
Похоже, мне нужно что-то сделать, чтобы удовлетворить концепцию Sentinel
iterator_range
, но я не смог понять, что именно. Любая помощь приветствуется!
Изменить: я компилирую с помощью gcc54 -std=c++14. Ошибки компиляции range v3/c++ довольно длинные, но вот фрагмент:
range-v3/include/range/v3/iterator_range.hpp:171:17: note: in expansion of macro 'CONCEPT_REQUIRES_'
CONCEPT_REQUIRES_(Sentinel<S, I>())>
^
range-v3/include/range/v3/utility/concepts.hpp:669:15: note: invalid template non-type parameter
>::type = 0 \
^
range-v3/include/range/v3/iterator_range.hpp:171:17: note: in expansion of macro 'CONCEPT_REQUIRES_'
CONCEPT_REQUIRES_(Sentinel<S, I>())>
i
выражения*i
и++i
должны быть правильно сформированы (хотя фактическое вычисление этих выражений может быть неправильным, например, для значений итератора, находящихся за концом). Добавление этих операторов к вашему типуiterator_t
может разрешить компиляцию. Вам также может понадобиться специализацияstd::iterator_traits
для вашего типаMyRange::iterator_t
. - person cdhowie   schedule 28.03.2017*i
и++i
, но все равно не компилируется. Также версия boost отлично компилируется (даже без них). Я думаю, что мы что-то упускаем здесь. - person skgbanga   schedule 28.03.2017error: no member named 'make_iterator_range' in namespace 'ranges::v3'; did you mean 'boost::make_iterator_range'?
, а не из-за того, что что-то связано сMyRange::iterator_t
. - person cdhowie   schedule 28.03.2017WeaklyIncrementable
требует, чтобы тип различия вашего итератора проходилstd::is_integral
. Я не уверен на 100%, где он пытается получить этот тип, но я предполагаю, чтоstd::iterator_traits<MyRange::iterator_t>::difference_type
. - person cdhowie   schedule 28.03.2017MyRange::iterator_t::difference_type
необходимо определить. Я предполагаю, что он также потребует, чтобыoperator-
возвращалdifference_type
для получения разницы между итераторами. - person cdhowie   schedule 28.03.2017iterator
фактически удовлетворяющим требованиям итератора, тогда ваш диапазон будет удовлетворять требованиям диапазона, и вам не нужноmake_iterator_range
. - person Casey   schedule 28.03.2017iterator
, упомянутые здесь: en.cppreference.com/w/cpp/concept /Iterator не требует многого. И ссылка на coliru: coliru.stacked-crooked.com/a/090f4b56b47b88ef (показано только для кода, а не для компиляции!) удовлетворяют всем требованиям. (по крайней мере я так думаю). И я думаю, что iterator_range предоставляет хорошие псевдонимы/типы, которые требуются для определенных алгоритмов. - person skgbanga   schedule 28.03.2017operator++(int)
) и (б) имеет не-const
operator*
. И нет, уверяю вас, чтоiterator_range
— это просто диапазон, как и любой другой, без особых качеств. Его цель — предоставить механизм формирования диапазона, когда у вас есть итератор и часовой. - person Casey   schedule 29.03.2017iterator_range
иmake_iterator_range
называлисьrange
иmake_range
.) - person Casey   schedule 29.03.2017