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

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

27.09.2015, 00:05. Показов 3920. Ответов 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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
Ответ Создать тему
Новые блоги и статьи
Вот уже год прошел, как у меня домен в reg.ru ...
Etyuhibosecyu 16.04.2026
И ничего они мне не сделали. Если отвязать карту, никакие услуги они не навяжут. Я бы с радостью продлил еще на два года, чтобы не мучиться с временным доменом и меня уже знали по red-star-soft. com,. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача №1: при указании работ (справочник РаботыПоРемонтуСпецтехники),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru