Идеальная пересылка итераторов: это слишком много? - PullRequest
0 голосов
/ 07 ноября 2018

В C ++ константность объекта передается через итераторы. std::begin(a) обычно возвращает A::iterator, если a не является постоянным, A::const_iterator, если a является постоянным.

Я попытался расширить эту концепцию до поведения при перемещении , чтобы улучшить общий код. Основная идея примерно такая:

struct A {
  using value_type = std::string;
  using iterator = AIter<A>;
  using const_iterator = AIter<A const>;
  using move_iterator = AIter<A &&>;

  iterator begin() &;
  iterator end() &;
  const_iterator begin() const &;
  const_iterator end() const &;
  move_iterator begin() &&;
  move_iterator end() &&;
};

template <typename A> struct AIter {
  using a_type = A;
  using value_type = typename std::decay_t<A>::value_type;
  using reference = std::conditional_t<
      std::is_rvalue_reference_v<A>, value_type &&,
      std::conditional_t<std::is_const_v<std::remove_reference_t<A>>,
                         value_type const &, value_type &>>;
};

Это немного запутанно, особенно условный тип в итераторе. Концепция заключается в том, что тип итератора полностью зависит от ссылочного типа из A.

К сожалению, проблема возникает, когда вместо прямого использования функций-членов я пытаюсь использовать std::begin и std::end (и все подобные), потому что они не предназначены для работы в совершенной пересылке манера. Здесь вы можете найти небольшую демонстрацию в проводнике компилятора, если вы хотите провести несколько тестов.

Учитывая текущую ситуацию, моя точка зрения:

  • Я слишком много спрашиваю у стандартных итераторов? Есть ли неожиданное поведение этого подхода? Я никогда не видел что-то вроде std::begin(std::move(a)) (вы обычно используете для этого std::make_move_iterator), но в общем коде я думаю, что использование std::begin(std::forward<A>(a)) может быть полезным ... или нет?
  • У меня нет четкого представления о том, как этот подход будет работать с диапазонами C ++ 20. Что ты думаешь?
  • Если вы считаете, что этот подход может быть полезным, считаете ли вы, что он может быть лучше при использовании метода .begin() или пользовательской бесплатной функции, которая выполняет совершенную пересылку ? Что-то вроде в ссылке на проводник компилятора.

РЕДАКТИРОВАТЬ : Nelfeal найден этот другой вопрос , который очень связан с моим.

...