Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
-21 / 3 / 0
Регистрация: 01.09.2017
Сообщений: 21

Хочу перегрузить iterator для пользовательского шаблонного класса контейнера

12.10.2018, 14:09. Показов 3227. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Осваивал шаблонные параметры шаблоны на примере шаблонов контейнерных классов, и открыл для себя дивный новый мир такого чудесного контейнера как std::list, где для произвольного доступа к элементам нужно пользоваться такими вещами как библиотека "iterator", инкрементами, декрементами этого самого итератора, многофункциональной функцией copy, которая умело оперирует такими методами как begin(), end(), итераторами самой библиотеки, а также созданными пользователем итераторами вида

C++
1
std::list<int>::iterator it = list2.begin();
О чём речь. Допустим, у меня есть пользовательский контейнер Array, который по функционалу напоминает std::vector. Методы begin()/end(), возвращающие ссылку на первый элемент/следующий после последнего, я успешно реализовал, работают с функцией copy. Как мне реализовать/перегрузить iterator таким образом чтобы я мог создать что-то такое и оно бы работало как тот же std::vector<int>::iterator

C++
1
Array<int>::iterator it = array0.begin();
Материалы по теме итераторов в основном только учат как ими пользоваться. Благодаря кое-какой документации с cppreference, если я правильно понял, iterator это класс, описанный внутри класса-контейнера. Как его правильно описать, и что в нём должно быть? Буду признателен за пример кода. Объявление класса Array

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
template <typename T, class Allocator = std::allocator<T>>
class Array
{
public:
    //   конструктор класса
    explicit Array(size_t size, const T& value = T());
 
    //   конструктор по умолчанию
    Array();
 
    //   деструктор
    ~Array();
 
    //   конструктор копирования
    Array(const Array & other);
    Array(const std::vector<T> & other);
 
    //   оператор присваивания
    Array& operator=(const Array & other);
 
    void swap(Array &other);
//   возвращает размер массива (количество элементов).
size_t size() const;
//T * data() const { return data_; };
 
//   две версии оператора доступа по индексу
T& operator[](size_t i);
const T& operator[](size_t i) const;
 
T& get(size_t i) { return data_[i]; };
const T& get(size_t i) const { return data_[i]; };
 
T& at(size_t i) { return data_[i]; };
const T& at(size_t i) const { return data_[i]; };
 
T* begin() { return &data_[0]; }
T* end() { return &data_[size_]; }
 
private:
    size_t size_;
    T * data_;
 
};
P.S. Ответы вроде "зачем тебе этот велосипед, пользуйся готовыми инструментами" просьба не оставлять
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.10.2018, 14:09
Ответы с готовыми решениями:

Перегрузить приведение типов для шаблонного класса
Хай. Имеется template &lt;class T&gt; class fraction { public: T top; T bot;

Как перегрузить операторы для шаблонного класса?
Собственно задание: Нужно написать класс описывающий обычный вектор на плоскости. Для этого класса вам нужно реализовать сложение,...

Перегрузить operator<<() для шаблонного класса (перегрузка оператора вывода)
Здравствуйте. Перегружаю оператор вывода для шаблонного класса. using namespace std; template &lt;class Element&gt; class List { ...

3
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
12.10.2018, 14:26
Цитата Сообщение от FeewrE Посмотреть сообщение
Как его правильно описать, и что в нём должно быть?
Можешь почитать тут о типах существующих итераторов и о требованиях, которые накладываются на каждый из них.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.10.2018, 20:27
Цитата Сообщение от FeewrE Посмотреть сообщение
чтобы я мог создать что-то такое и оно бы работало как тот же std::vector<int>::iterator
Array<int>::iterator it = array0.begin();
материал немножко покамест сыроват.
на бою я его покамест ещё не использую,
но для обучения вполне сойдет я думаю.

здесь на самом деле 3 файла-хэдера, и 1 файл-спп
я их объединил в один для онлайн демонстрации.

пример иллюстрация изготовления собственных итераторов в двух вариантах:
- обычные (не рекурсивные)
- рекурсивные (для обхода деревьев)

пример содержит рецепт изготовления простенького деревца.

ссылочка на онлайн демонстрацию
https://rextester.com/GHOP72469

к сожалению сам текст не влез в сообщение.
форум не хочет принимать 32266 буковок.
максимум - 25000.

поэтому исходник отправляю в виде вложения.
а здесь оставлю только дизайн использования:

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
159
160
161
162
163
164
// пример использования:
 
#include <tools/iteratos.hpp> // <--- допустим здесь живут наши итераторы
 
#include <iostream>
#include <memory>
#include <string>
#include <list>
 
// <--- пример рекурсивного деревца
    class form
    {
        using sform          = ::std::shared_ptr<form>;
        using container      = ::std::list<sform>;
        
        // iterator`s contract
        dDECLARE_FRIEND_ITERATORS(form);
        container&       get_container()      { return m_container; }
        const container& get_container()const { return m_container; }
 
        static const form* get_pointer(const container::const_iterator& it)
            { return (*it).get(); }
        
    public:
        // рекурсивные
        using iterator       
            = ::tools::recursieve_iterator<form>;
        
        using const_iterator 
            = ::tools::recursieve_iterator<const form>;
        
        // не рекурсивные
        using non_rec_iterator       
            = ::tools::iterator<form>;
        
        using const_non_rec_iterator 
            = ::tools::iterator<const form>;
        
    public:
        // iterator`s contract
        auto begin() { return iterator(*this); }
        
        auto begin() const { return const_iterator(*this); }
        
        auto end()   
            { return iterator(*this, false); }
        
        auto end() const
            { return const_iterator(*this, false); }
    private:
        form(const ::std::string& n, form* p)
            : m_name(n)
            , m_parent(p)
            , m_container()
        {}
    public:
        form(const ::std::string& n)
            : form(n, nullptr)
        {}
 
        form(const form& rhs)
            : m_name(rhs.m_name)
            , m_parent(rhs.m_parent)
            , m_container(rhs.m_container)
        {}
        form& operator=(const form& rhs)
        {
            m_name      = rhs.m_name;
            m_parent    = rhs.m_parent;
            m_container = rhs.m_container;
            return *this;
        }
 
        form& add(const ::std::string& name)
        {
            auto obj = std::make_shared<form>(name);
            obj->m_parent = this;
            m_container.emplace_back(obj);
            return *obj;
        }
 
        form& done()
        {
            if(m_parent)
                return *m_parent;
            return *this;
        }
 
        form& front()
        {
            assert(!m_container.empty());
            return *m_container.front();
        }
 
        const ::std::string& get_name()const
            { return m_name; }
 
        bool operator==(const form& rhs)const
            { return m_name == rhs.m_name; }
        bool operator!=(const form& rhs)const
            { return !this->operator ==(rhs); }
        
        
        const container& get_children() const
            { return m_container; }
        
    private:
        ::std::string  m_name;
        form*          m_parent;
        container      m_container;
    };
 
void view(const form& widget, const size_t depth = 0 )
{
    std::cout << std::string(depth, ' ') 
        << widget.get_name()
        << '\n';
 
    const auto& children = widget.get_children();
    for(const auto& pChild: children)
        view(*pChild, depth + 1);
}
 
int main()
{
 
   // --- наполняем наше деревце дочерними элементами
 
    auto widget = form("root")
        .add("==1==")
            .add("==1.1==").done()
            .add("==1.2==").done()
            .add("==1.3==").done()        
        .done()
        .add("==2==")
            .add("==2.1==").done()
            .add("==2.2==")
                .add("==2.2.1==").done()
                .add("==2.2.2==").done()
                .add("==2.2.3==").done()
            .done()
            .add("==2.3==").done()        
        .done()
    .done();    
    
   // показываем
    view(widget);
    
    std::cout << "\n";
    
    // --- рекурсивно бежим по элементам контейнера
    for(auto&& element: widget)
        std::cout << element.get_name() << '\n';
    
    std::cout << "\n";
    
    // --- итератор заказывали?
    form::iterator i = widget.begin();
    form::iterator e = widget.end();
    while( i != e )
        std::cout << i->get_name() << '\n',
        ++i;
 
}
Вложения
Тип файла: 7z iterators.7z (4.5 Кб, 4 просмотров)
0
-21 / 3 / 0
Регистрация: 01.09.2017
Сообщений: 21
03.02.2019, 14:20  [ТС]
Вдруг кому ещё нужно. Поперед батька, как говорится...

https://stepik.org/lesson/53378/step/13?unit=31453
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.02.2019, 14:20
Помогаю со студенческими работами здесь

Перегрузить оператор () для пользовательского класса Matrix
Суть, есть класс matrix , есть int **p(матрица) и int row, col; , нужно перегрузить оператор () для вывода элемента массива, в задание...

Как перегрузить оператор "+" для шаблонного класса, инстанцированного разными типами?
подскажите как перегрузить оператор &quot;+&quot; для шаблона , инстанцированных разными типами ...

Разработка шаблонного класса-контейнера
Помогите пожалуйста разобраться! решаю задачу и не могу найти солюшен, всё очень просто, вот задача: Необходимо разработать класс...

Для шаблонного класса перегрузить оператор присваивания, copy-конструктор, объекты cin и cout, оператор *
Помогите в следующем: Для класса шаблона следует перегрузить оператор присваивания, конструктор копирования, бинарный оператор суммы «*»,...

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра?
header.h template &lt;class T&gt; class MyVector { public: void swap(MyVector&lt;T&gt;Vector); } template &lt;class T&gt; void...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru