Задать вопрос
Dyikot
@Dyikot

Почему view не подходит под концепт range?

Вот пример:
std::vector<int> r1 = { 0, 1, 2, 3, 4 };
std::vector<int> r2 = { 5, 6, 7, 8, 9 };

auto view = Views::ConcatView(r1, r2);
for(auto i : view)
{
	std::cout << std::format("{} ", i);
}

static_assert(std::ranges::range<decltype(view)>); // false

При этом цикл проходит, но вот концепт не проходит.

Вот
код view

template<view TView, view TOtherView>
		requires std::same_as<range_value_t<TView>, range_value_t<TOtherView>>
	class ConcatView : public view_interface<ConcatView<TView, TOtherView>>
	{
	private:
		TView _view;
		TOtherView _otherView;

		class ConcatIterator
		{
		private:
			ConcatView* _parent {};
			bool _isInSecond;
			iterator_t<TView> _firstIterator;
			iterator_t<TOtherView> _secondIterator;
		public:
			using value_type = range_value_t<TView>;
			using difference_type = range_difference_t<TView>;
			using reference = range_reference_t<TView>;

			constexpr ConcatIterator(ConcatView& parent, bool isEnd):
				_parent(&parent),
				_isInSecond(false)
			{
				auto& first = parent._view;
				auto& second = parent._otherView;

				if(isEnd)
				{
					_firstIterator = first.end();
					_secondIterator = second.end();
					_isInSecond = true;
				}
				else
				{
					_firstIterator = first.begin();
					_secondIterator = second.begin();

					if(_firstIterator == first.end())
					{
						_isInSecond = true;
					}
				}
			}

			constexpr reference operator*() const
			{
				if(_isInSecond)
				{
					return *_secondIterator;
				}
				else
				{
					return *_firstIterator;
				}
			}

			constexpr ConcatIterator& operator++()
			{
				if(_isInSecond)
				{
					++_secondIterator;
				}
				else
				{
					if(++_firstIterator == _parent->_view.end())
					{
						_isInSecond = true;
						_secondIterator = _parent->_otherView.begin();
					}
				}

				return *this;
			}

			constexpr ConcatIterator operator++(int)
			{
				ConcatIterator tmp = *this;
				++(*this);
				return tmp;
			}

			constexpr bool operator==(const ConcatIterator& other) const
			{
				return _isInSecond == other._isInSecond &&
					(_isInSecond
						? _secondIterator == other._secondIterator
						: _firstIterator == other._firstIterator);
			}
		};
	public:
		constexpr ConcatView(TView range, TOtherView otherRange):
			_view(std::move(range)),
			_otherView(std::move(otherRange))
		{}

		ConcatView(const ConcatView&) requires std::copyable<TView> = default;
		ConcatView(ConcatView&&) = default;

		constexpr auto begin()
		{
			return ConcatIterator(*this, false);
		}

		constexpr auto end()
		{
			return ConcatIterator(*this, true);
		}

		constexpr auto size() requires sized_range<TView> && sized_range<TOtherView>
		{
			return std::ranges::size(_view) + std::ranges::size(_otherView);
		}

		ConcatView& operator=(const ConcatView&) requires std::copyable<TView> = default;
		ConcatView& operator=(ConcatView&&) = default;
	};

	template<typename TRange, typename TOtherRange>
	ConcatView(TRange&&, TOtherRange&&) -> ConcatView<all_t<TRange>, all_t<TOtherRange>>;

  • Вопрос задан
  • 42 просмотра
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Разработчик C++
    9 месяцев
    Далее
  • Нетология
    Специалист по информационной безопасности + нейросети
    12 месяцев
    Далее
  • Компьютерная академия «TOP»
    Учебная программа “Разработка программного обеспечения”
    30 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы