Как определить итератор для особого случая, чтобы использовать его в цикле for с помощью ключевого слова auto

0

Я хотел бы определить следующий код, чтобы иметь возможность использовать его как "for (auto x: c0) {printf ("% я ", x);}"

Но я ничего не понимаю, и я искал его некоторое время.

Ошибка, которую я получаю: ошибка: неверный аргумент типа унарного '* (есть' CC :: iterator {aka int})

#include <stdio.h>

class CC{
  int a[0x20];
  public: typedef int iterator;
  public: iterator begin(){return (iterator)0;}
  public: iterator end(){return (iterator)0x20;}
  public: int& operator*(iterator i){return this->a[(int)i];}
} ;

int main(int argc, char **argv)
{ class CC c0;
  for (auto x:c0){
    printf("%i ",x);
  }
  printf("\n");
  return 0;
}
  • 0
    Вы можете думать об итераторах как о возможных улучшенных указателях. Это итератор, который разыменовывается.
  • 1
    В C ++ спецификаторы доступа (например, public: :) применяются ко всем следующим объявлениям в определении класса. Вам не нужна public: перед каждым объявлением в CC вам нужен только один, чтобы отделить рядовых от публики.
Теги:

2 ответа

3

Кажется, вы пытаетесь использовать int качестве типа итератора, используя operator*() член operator*() в качестве операций надписей. Это не сработает:

  1. Определенный вами operator*() является двоичным оператором (умножением), а не унарной операцией разыменования.
  2. Вы не можете перегружать операторов для встроенных типов, а тип итератора должен иметь оператор разыменования.

Для того, чтобы иметь возможность использовать диапазон на основе for вам необходимо создать тип переадресации итератора, который нуждается в несколько операций:

  1. Управление жизненным циклом, т.е. Конструктор копирования, назначение копии и уничтожение (обычно сгенерированные являются достаточными).
  2. Позиционирование, т. operator++() и operator++(int).
  3. Доступ к значениям, т. operator->() operator*() и потенциально operator->().
  4. Проверка достоверности, т. operator==() и operator!=().

Что-то вроде этого должно быть достаточно:

class custom_iterator {
    int* array;
    int  index;
public:
    typedef int         value_type;
    typedef std::size_t size_type;
    custom_iterator(int* array, int index): array(array), index(index) {}
    int& operator*()             { return this->array[this->index]; }
    int const& operator*() const { return this->array[this->index]; }
    custom_iterator& operator++() {
        ++this->index;
        return *this;
    }
    custom_iterator  operator++(int) {
        custom_iterator rc(*this);
        this->operator++();
        return rc;
    }
    bool operator== (custom_iterator const& other) const {
        return this->index = other.index;
    }
    bool operator!= (custom_iteartor const& other) const {
        return !(*this == other);
    }
};

Затем методы begin() и end() возвращают подходящую версию этого итератора. Вы можете подключить итератор с подходящей std::iterator_traits<...> но я не думаю, что они необходимы для использования диапазона на основе for.

1

Dietmar Kühl хорошо объяснил, почему ваш код не работает: вы не можете заставить int вести себя как итератор.

Для данного случая подходящий итератор может быть определен как указатель на int. Следующий код проверяется на ideone:

#include <stdio.h>

class CC{
  int a[0x20];
  public: typedef int* iterator;
  public: iterator begin() {return a;}
  public: iterator end() {return a+0x20;}
} ;

int main(int argc, char **argv)
{
  class CC c0;
  int i = 0;
  for (auto& x:c0){
    x = ++i;
  }
  for (auto x:c0){
    printf("%i ",x);
  }
  printf("\n");
  return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню