Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Свой итератор в связке с for_each  (Прочитано 12753 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Setuper
Интересующийся

ru
Offline Offline

« : 24-08-2009 20:35 » 

Столкнулся с проблемой. В классе создаю свой итератор и пытаюсь прогнать цикл for_each, однако, не получается выполнить даже предварительную компиляцию. Помогите. Что я не то делаю, и что нужно сделать чтобы всё работало?

Цикл for_each со стандартными контейнерами (например вектором) работает на отлично, однако, мне нужно сделать свой собственный итератор.  А черт его знает...

Код:
#include <iostream>
#include <algorithm>
using namespace std;

class MyClass
{
public:
  int * data;
  class iterator
  {
  public:
    iterator(){}
    bool operator == (const iterator &it){return true;}
    bool operator != (const iterator &it){return false;}
    iterator & operator ++(){return *this;}
    int operator *(){return 0;}
  };

  iterator begin(){
    return iterator();
  }
  iterator end(){
    return iterator();
  }
};

void sss(int v){}
int main()
{
  MyClass A;
  std::for_each( A.begin(), A.end(), sss );
  return 0;
}
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 24-08-2009 20:42 » 

Версия компилятора?
Код ошибки?

На GCC у меня твоя программа скомпилировалась нормально.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Setuper
Интересующийся

ru
Offline Offline

« Ответ #2 : 24-08-2009 20:49 » new

VS 2008

error C2039: 'iterator_category' : is not a member of 'MyClass::iterator'
Записан
Setuper
Интересующийся

ru
Offline Offline

« Ответ #3 : 24-08-2009 20:52 » 

Ошибка не одна. Их много. Видимо vs может работать только со стандартными контейнерами

Цитата
Error   1   error C2039: 'iterator_category' : is not a member of 'MyClass::iterator'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   764
Error   2   error C2146: syntax error : missing ';' before identifier 'iterator_category'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   764
Error   3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\program files\microsoft visual studio 9.0\vc\include\xutility   764
Error   4   error C2602: 'std::iterator_traits<_Iter>::iterator_category' is not a member of a base class of 'std::iterator_traits<_Iter>'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   764
Error   5   error C2868: 'std::iterator_traits<_Iter>::iterator_category' : illegal syntax for using-declaration; expected qualified-name   c:\program files\microsoft visual studio 9.0\vc\include\xutility   764
Error   6   error C2039: 'value_type' : is not a member of 'MyClass::iterator'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   765
Error   7   error C2146: syntax error : missing ';' before identifier 'value_type'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   765
Error   8   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\program files\microsoft visual studio 9.0\vc\include\xutility   765
Error   9   error C2602: 'std::iterator_traits<_Iter>::value_type' is not a member of a base class of 'std::iterator_traits<_Iter>'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   765
Error   10   error C2868: 'std::iterator_traits<_Iter>::value_type' : illegal syntax for using-declaration; expected qualified-name   c:\program files\microsoft visual studio 9.0\vc\include\xutility   765
Error   11   error C2039: 'difference_type' : is not a member of 'MyClass::iterator'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   766
Error   12   error C2146: syntax error : missing ';' before identifier 'difference_type'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   766
Error   13   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\program files\microsoft visual studio 9.0\vc\include\xutility   766
Error   14   error C2602: 'std::iterator_traits<_Iter>::difference_type' is not a member of a base class of 'std::iterator_traits<_Iter>'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   766
Error   15   error C2868: 'std::iterator_traits<_Iter>::difference_type' : illegal syntax for using-declaration; expected qualified-name   c:\program files\microsoft visual studio 9.0\vc\include\xutility   766
Error   16   error C2039: 'pointer' : is not a member of 'MyClass::iterator'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   768
Error   17   error C2146: syntax error : missing ';' before identifier 'pointer'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   768
Error   18   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\program files\microsoft visual studio 9.0\vc\include\xutility   768
Error   19   error C2602: 'std::iterator_traits<_Iter>::pointer' is not a member of a base class of 'std::iterator_traits<_Iter>'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   768
Error   20   error C2868: 'std::iterator_traits<_Iter>::pointer' : illegal syntax for using-declaration; expected qualified-name   c:\program files\microsoft visual studio 9.0\vc\include\xutility   768
Error   21   error C2039: 'reference' : is not a member of 'MyClass::iterator'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   769
Error   22   error C2146: syntax error : missing ';' before identifier 'reference'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   769
Error   23   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int   c:\program files\microsoft visual studio 9.0\vc\include\xutility   769
Error   24   error C2602: 'std::iterator_traits<_Iter>::reference' is not a member of a base class of 'std::iterator_traits<_Iter>'   c:\program files\microsoft visual studio 9.0\vc\include\xutility   769
Error   25   error C2868: 'std::iterator_traits<_Iter>::reference' : illegal syntax for using-declaration; expected qualified-name   c:\program files\microsoft visual studio 9.0\vc\include\xutility   769
Error   26   error C2665: 'std::_Debug_range2' : none of the 2 overloads could convert all the argument types   c:\program files\microsoft visual studio 9.0\vc\include\xutility   1572
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #4 : 24-08-2009 21:01 » 

Открываеш в алгоритмах функцию for_each и смотриш. Какие именно методы итератора используются. Первая ошибка говорит, что не определен метод iterator_category. А все остальные ошибки как правило уже идут паравозом. Разрули первую ошибку, а дальше остальны могут сами исчезнуть.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-08-2009 21:02 » 

Всё правильно. Самописный итератор не удовлетворяет требованиям, налагаемым алгоритмом for_each. Нужно как минимум определить теги (категории), которым итератор соответствует, а также traits - характеристики итерируемого типа.
Записан
Setuper
Интересующийся

ru
Offline Offline

« Ответ #6 : 24-08-2009 21:20 » 

Попробовал определить в итераторе указанные в ошибках типы.

Код:
class iterator
{
public:
  typedef iterator iterator_category;
  typedef int value_type;
  typedef int difference_type;
  typedef int* pointer;
  typedef int& reference;
  iterator(){}
  bool operator == (const iterator &it){return true;}
  bool operator != (const iterator &it){return false;}
  iterator & operator ++(){return *this;}
  int operator *(){return 0;}
};

Получил одну ошибку:
Цитата
Error   1   error C2665: 'std::_Debug_range2' : none of the 2 overloads could convert all the argument types   c:\program files\microsoft visual studio 9.0\vc\include\xutility   1572
"Ни одна из перегруженных функций не может преобразовать все типы аргумента"

Иду по ошибке
Код:
template<class _InIt> inline
void __CLRCALL_OR_CDECL _Debug_range(_InIt _First, _InIt _Last, const wchar_t *_File, unsigned int _Line)
{ // test iterator pair for valid range
_Debug_range2(_First, _Last, _File, _Line, _Iter_cat(_First)); // <--------- УКАЗЫВАЕТ, ЧТО ТУТ ОШИБКА
}

Лезу в функцию _Debug_range2:
Код:
template<class _InIt> inline
void __CLRCALL_OR_CDECL _Debug_range2(_InIt, _InIt, const wchar_t *, unsigned int ,
input_iterator_tag)
{ // test iterator pair for valid range, arbitrary iterators
}

В общем залез в какие-то дебри... На юниксах вроде как всё нормально работает, а тут такая петрушка  Здесь была моя ладья...
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 24-08-2009 22:14 » 

Смотри в направлении iterator_category. Насколько я помню, там предопределённые типы были. На память не помню, но сдаётся, что твой typedef в корне неверный Улыбаюсь А в unix-реализации, должно быть, просто не делается эта проверка.
Записан
Setuper
Интересующийся

ru
Offline Offline

« Ответ #8 : 24-08-2009 23:08 » 

Посмотрев реализацию функции for_each, решил переопределить её для винды безо всяких проверок. Вроде всё нормально компилится.
Буду смотреть что из этого выйдет в большом проекте...

Код:
#ifdef _WIN32
template<class T1, class T2> inline
  T2 For_each(T1 first, T1 last, T2 func)
  {
    try{
      for(; first != last; ++first) func(*first);
    }catch(...){std::cout<<"for_each fatal error"<<endl; throw "for_each fatal error";}
    return func;
  }
#else
template<class T1, class T2> inline
  T2 For_each(T1 first, T1 last, T2 func)
  {
    return std::for_each(first, last, func);
  }
#endif // _WIN32
« Последнее редактирование: 24-08-2009 23:13 от Setuper » Записан
bgaifullin
Гость
« Ответ #9 : 03-12-2009 10:17 » 

необходимо наследоваться от класса
template<class _Category,
   class _Ty,
   class _Diff = ptrdiff_t,
   class _Pointer = _Ty *,
   class _Reference = _Ty&,
   class _Base_class = _Iterator_base>
      struct _Iterator_with_base
         : public _Base_class

   {   // base type for all iterator classes
   typedef _Category iterator_category;
   typedef _Ty value_type;
   typedef _Diff difference_type;
   typedef _Diff distance_type;   // retained
   typedef _Pointer pointer;
   typedef _Reference reference;
   };
где класс категорий может быть  std::forward_iterator_tag или bidirectional_iterator_tag ...
с остальным думаю разберешься. Ага
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines