С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690

Реализация std::list<>::begin()

27.09.2015, 00:05. Показов 3835. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопрос строго для знатоков реализации STL.
Каким образом реализована "перегрузка" у списка метода begin() только по возвращаемому значению? Т.е. этот метод может возвращать как iterator, так и const_iterator
Я лично вижу тут два пути : либо const_iterator наследуется от iterator (или наоборот), либо const_iterator является другом iterator (или наоборот). Но хочется знать уж наверняка (реализую свой список-велосипед, и не знаю как лучше поступить)
P.S. пытался курить сорцы list.h, но там просто ад
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.09.2015, 00:05
Ответы с готовыми решениями:

Реализация std::list, сложность list::size()
Часто приходилось пользоваться Listом, но сейчас столкнулся с небольшой неоднозначностью. Согласно документации, метод size() в 11...

Std::begin() ,std::end(),std::copy
...// int main() { std::vector&lt;double&gt; data;//Работает cout &lt;&lt; std::begin(data); double *data=new double; ...

Реализация класса MyString. Стандартная библиотека, std::string, std::vector
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в классе MyString и почему ошибка выдается???#include...

13
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.09.2015, 00:08
const_terator begin() const;
iterator begin();

т.е. константный метод возвращает константный итератор, и неконстантный - неконстантный
какой из них звать - компилятор определяет из контекста вызова метода.
0
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
27.09.2015, 00:09  [ТС]
Цитата Сообщение от Perfilov Посмотреть сообщение
т.е. константный метод возвращает константный итератор, и неконстантный - неконстантный
какой из них звать - компилятор определяет из контекста вызова метода.
Не определяет.
По стандарту, методы не могут быть перегружены только по возвращаемому значению - сигнатура полностью совпадает
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.09.2015, 00:12
константность\неконстантность метода в сигнатуру входит. или как тогда по вашему разруливается то, о чем пишет ТС?
0
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
27.09.2015, 00:19  [ТС]
Цитата Сообщение от Perfilov Посмотреть сообщение
константность\неконстантность метода в сигнатуру входит. или как тогда по вашему разруливается то, о чем пишет ТС?
Хм, тогда я чего-то не понимаю.
Вот код :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
template<typename T>
class Linked_list
{
public:
    class Iterator
    {
    public:
        Iterator();
        Iterator(const Iterator &iterator);
 
        Iterator& operator=(const Iterator &right);
        bool operator!=(const Iterator &right) const;
        bool operator==(const Iterator &right) const;
 
        T& operator*() const;   
        T* operator->() const;
 
        Iterator& operator++();
        Iterator operator++(int);
        Iterator& operator--();
        Iterator operator--(int);
    };
 
    class Const_Iterator
    {
    public:
        Const_Iterator();
        Const_Iterator(const Const_Iterator &iterator);
 
        Const_Iterator& operator=(const Const_Iterator &right);
        bool operator!=(const Const_Iterator &right) const;
        bool operator==(const Const_Iterator &right) const;
 
        const T& operator*() const;
        const T* operator->() const;
 
        Const_Iterator& operator++();
        Const_Iterator operator++(int);
        Const_Iterator& operator--();
        Const_Iterator operator--(int);
    };
 
    Iterator begin();   
    Iterator end();     
    
    Const_Iterator begin() const;
    Const_Iterator end() const;
};
Вот использование:
C++
1
2
3
Linked_list<int> list;
...
for (Linked_list<int>::Const_Iterator iter = list.begin(); iter != list.end(); iter++)
Ну и результат:
Ошибка 1 error C2440: инициализация: невозможно преобразовать "Linked_list<int>::Iterator" в "Linked_list<int>::Const_Iterator"
Ошибка 2 error C2679: бинарный "!=": не найден оператор, принимающий правый операнд типа "Linked_list<int>::Iterator" (или приемлемое преобразование отсутствует)
Т.е. компилятор хочет, чтобы я ему предоставил конструктор "преобразования"
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.09.2015, 00:28
ну да. это вроде логично. например неконстантный инт может к константному преобразоваться неявно. логично это ожидать и от итератора. явно кастить неконстантный в константный - это ахтунг а не код будет. а вот как это сделано - я не скажу, не знаю. либо наследованием, либо у константного есть конструктор или еще как-то. нет литературы под рукой глянуть и компа нормального тоже.

Добавлено через 3 минуты
еще что-то слышал про методы std::cbegin std::cend, которые должны в вашем случае решить проблему преобразования. ибо они будут возвращать константные итераторы. но хз стандартные ли они или нет. std::begin std::end - точно в стандарте
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.09.2015, 00:36
Nikitko_Cent, собственно, можно ведь просто посмотреть как это реализовано в стандартной библиотеке.
Например в реализации std:: в gcc используется конструктор преобразования nonconst -> const
C++
1
2
3
4
5
6
      typedef _List_iterator<_Tp>                iterator;
     
      //.................
 
      _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT
      : _M_node(__x._M_node) { }
1
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
27.09.2015, 00:39  [ТС]
DrOffset, так вот, я к тому, каким образом реализован доступ к приватному (я надеюсь ) полю объекта __x из другого класса:
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
Я лично вижу тут два пути : либо const_iterator наследуется от iterator (или наоборот), либо const_iterator является другом iterator (или наоборот). Но хочется знать уж наверняка (реализую свой список-велосипед, и не знаю как лучше поступить)
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.09.2015, 00:44
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
так вот, я к тому, каким образом реализован доступ к приватному (я надеюсь ) полю объекта x из другого класса:
Они не приватные. Это структура.
Ну если очень хочется засунуть в приват, то можно использовать friend class Iterator; для const версии.

Добавлено через 2 минуты
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
P.S. пытался курить сорцы list.h, но там просто ад
Кстати, не знаю уж чего там адового. Нормальный код.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  template<typename _Tp>
    struct _List_iterator
    {
      typedef _List_iterator<_Tp>                _Self;
      typedef _List_node<_Tp>                    _Node;
 
      typedef ptrdiff_t                          difference_type;
      typedef std::bidirectional_iterator_tag    iterator_category;
      typedef _Tp                                value_type;
      typedef _Tp*                               pointer;
      typedef _Tp&                               reference;
 
      _List_iterator() _GLIBCXX_NOEXCEPT
      : _M_node() { }
 
      explicit
      _List_iterator(__detail::_List_node_base* __x) _GLIBCXX_NOEXCEPT
      : _M_node(__x) { }
 
      _Self
      _M_const_cast() const _GLIBCXX_NOEXCEPT
      { return *this; }
 
      // Must downcast from _List_node_base to _List_node to get to _M_data.
      reference
      operator*() const _GLIBCXX_NOEXCEPT
      { return static_cast<_Node*>(_M_node)->_M_data; }
 
      pointer
      operator->() const _GLIBCXX_NOEXCEPT
      { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
 
      _Self&
      operator++() _GLIBCXX_NOEXCEPT
      {
    _M_node = _M_node->_M_next;
    return *this;
      }
 
      _Self
      operator++(int) _GLIBCXX_NOEXCEPT
      {
    _Self __tmp = *this;
    _M_node = _M_node->_M_next;
    return __tmp;
      }
 
      _Self&
      operator--() _GLIBCXX_NOEXCEPT
      {
    _M_node = _M_node->_M_prev;
    return *this;
      }
 
      _Self
      operator--(int) _GLIBCXX_NOEXCEPT
      {
    _Self __tmp = *this;
    _M_node = _M_node->_M_prev;
    return __tmp;
      }
 
      bool
      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
      { return _M_node == __x._M_node; }
 
      bool
      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
      { return _M_node != __x._M_node; }
 
      // The only member points to the %list element.
      __detail::_List_node_base* _M_node;
    };
 
  /**
   *  @brief A list::const_iterator.
   *
   *  All the functions are op overloads.
  */
  template<typename _Tp>
    struct _List_const_iterator
    {
      typedef _List_const_iterator<_Tp>          _Self;
      typedef const _List_node<_Tp>              _Node;
      typedef _List_iterator<_Tp>                iterator;
 
      typedef ptrdiff_t                          difference_type;
      typedef std::bidirectional_iterator_tag    iterator_category;
      typedef _Tp                                value_type;
      typedef const _Tp*                         pointer;
      typedef const _Tp&                         reference;
 
      _List_const_iterator() _GLIBCXX_NOEXCEPT
      : _M_node() { }
 
      explicit
      _List_const_iterator(const __detail::_List_node_base* __x)
      _GLIBCXX_NOEXCEPT
      : _M_node(__x) { }
 
      _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT
      : _M_node(__x._M_node) { }
 
      iterator
      _M_const_cast() const _GLIBCXX_NOEXCEPT
      { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); }
 
      // Must downcast from List_node_base to _List_node to get to
      // _M_data.
      reference
      operator*() const _GLIBCXX_NOEXCEPT
      { return static_cast<_Node*>(_M_node)->_M_data; }
 
      pointer
      operator->() const _GLIBCXX_NOEXCEPT
      { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
 
      _Self&
      operator++() _GLIBCXX_NOEXCEPT
      {
    _M_node = _M_node->_M_next;
    return *this;
      }
 
      _Self
      operator++(int) _GLIBCXX_NOEXCEPT
      {
    _Self __tmp = *this;
    _M_node = _M_node->_M_next;
    return __tmp;
      }
 
      _Self&
      operator--() _GLIBCXX_NOEXCEPT
      {
    _M_node = _M_node->_M_prev;
    return *this;
      }
 
      _Self
      operator--(int) _GLIBCXX_NOEXCEPT
      {
    _Self __tmp = *this;
    _M_node = _M_node->_M_prev;
    return __tmp;
      }
 
      bool
      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
      { return _M_node == __x._M_node; }
 
      bool
      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
      { return _M_node != __x._M_node; }
 
      // The only member points to the %list element.
      const __detail::_List_node_base* _M_node;
    };
0
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
27.09.2015, 00:45  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Они не приватные. Это структура.
Это я чтоли смогу из любого куска кода написать iter._M_node = ... ? (относительно gcc)
Интересная картина...
0
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
27.09.2015, 00:48
у итераторов может быть общий предок, в котором этиданные - протектед. итого, откуда угодно не будет доступа. да и другими способами можно это порешать. вот до студии добрался. там преобразования за счет наследования работают:

C++
1
2
3
template<class _Mylist>
    class _List_iterator
        : public _List_const_iterator<_Mylist>
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
27.09.2015, 00:48
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
Это я чтоли смогу из любого куска кода написать iter._M_node = ... ? (относительно gcc)
Ну и что. Если это не документировано, считай этого нет.
Взять, допустим, структуру FILE из С. Вот ты много ли знаешь о ее содержимом? Между тем, оно точно так же открыто всем на обозрение. Конечно, контракт, контролируемый на этапе компиляции - это хорошо, но это не обязательное требование.
0
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
27.09.2015, 00:54  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Кстати, не знаю уж чего там адового. Нормальный код.
Я пишу в VC++, там как то всё сложнее реализовано. Я тупо не могу найти код реализации константного итератора
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.09.2015, 01:00
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
DrOffset, так вот, я к тому, каким образом реализован доступ к приватному (я надеюсь ) полю объекта __x из другого класса
Ну, мне нравится такой подход:
C++
1
2
3
4
5
6
7
8
template<bool is_const_iterator>
class my_iterator
{
public:
    my_iterator(const my_iterator<false>&src):data(src.data){}
private:
    std::conditional<is_const_iterator,const int*,int*>::type data;
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.09.2015, 01:00
Помогаю со студенческими работами здесь

Какая реализация лучше? std::pointer_to_binary_function vs std::function
Какая реализация (set_p или set_f) лучше /современнее / эффективнее ? pointer_to_binary_function в С++11 объявлен как deprecated. Правильно...

Потокобезопасность std::map::end, std::list::end
Собсна сабж, могу ли я без синхронизаций выполнять подобного рода код if (myIter != map.end()) // != list.end() {...} myIter =...

Разъясните код пжлст(выдает ошибку:cannot convert from 'class std::list<class c_bullet *,class std::allocator<class c_bullet *> >::iterator' to 'int')
Есть такие строки: std::list&lt;c_bullet*&gt; Bullets; ... for(auto i = Bullets.begin(); i != Bullets.end(); /**/) В строке цикла вот...

Вопросы по std::list
1. Как обменять в списке два его элемента? Желательно большое быстродействие :) т.е. без удалить оба а потом добавить в другом порядке,...

Вопрос по std::list
Не произойдёт ли здесь какая-нибудь ошибка после удаления элемента из списка? std::list&lt;int&gt; myList; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru