Итераторы STL. Проблема увеличения и уменьшения итераторов в векторах

   
На этом шаге мы рассмотрим одну особенность использования операции увеличения/уменьшения итераторов.

   
При применении в векторах операторов увеличения и уменьшения к итераторам возникает странная проблема. Вообще
говоря, увеличение и уменьшение временных итераторов разрешено, но для векторов и строк оно обычно запрещено.
Рассмотрим следующий пример:

  std::vector<int> coll;
  .   .   .   .   .
  // Сортировка, начиная со второго элемента 
  // - НЕПЕРЕНОСИМАЯ версия 
  if (coll.size() > 1) {
    sort(++coll.begin(), coll.end()); 
  }

   
Обычно компиляция строки с вызовом sort() завершается неудачей, но если заменить вектор деком,
компиляция пройдет нормально. Иногда программа компилируется даже для векторов - это зависит от реализации
класса vector.

   
Дело в том, что векторные итераторы обычно реализуются в виде обычных указателей. Для всех базовых типов данных,
в том числе и для указателей, модификация временных значений запрещена. С другой стороны, для структур и
классов она разрешена. Следовательно, если итератор реализован в виде обычного указателя, программа не
компилируется; если итератор реализован в виде класса, компиляция проходит успешно. Для деков, списков,
множеств и отображений такой проблемы не существует, поскольку в них итераторы в принципе не реализуются в
виде обычных указателей, но для векторов все зависит от реализации. В большинстве реализаций задействованы
обычные указатели. Но, например, в "безопасной" версии STL итераторы реализованы в виде классов. Чтобы
приведенный выше фрагмент был переносимым, достаточно определить промежуточный объект:

  std::vector<int> coll;
  .   .   .   .   .
  // Сортировка, начиная со второго элемента 
  // - ПЕРЕНОСИМАЯ версия 
  if (coll.size() > 1) {
    std::vector<int>::iterator beg = coll .begin(); 
    sort (++coll.beg, coll.end()); 
  }

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

   
Со следующего шага мы начнем рассматривать вспомогательные функции итераторов.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий