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

Error: Выдаёт ошибку C2679 binary "[": не найден оператор, принимающий правый операнд типа "тип"

28.10.2022, 20:21. Показов 1948. Ответов 41

Студворк — интернет-сервис помощи студентам
В общем, проблемка такая. Я в программировании не особо силён. Нужно было построить класс для работы с односвязным списком. Элементы списка – целые числа. Создать список List1. Построить список List2, содержащий порядковые номера
максимальных элементов списка List1.

Проблемка в том, что мне просит компилятор перегрузить оператор индексирования [], только вот перегрузка имеется. Что делать, ума не приложу... В коде есть лишние функции, которые не используются, это норма

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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include <iostream>
using namespace std;
 
/* оДНОсвязный список */
 
template <typename T> /* класс должен быть шаблонным */
class List
{
    
public:
    List(); /* конструктор */
    ~List(); /* деструктор */
    
    void pop_front();       /* прототип метода. Его задача - удалить первый элемент списка */
    void push_back(T data); /* прототип метода. Push_back - добавить данные в конец списка */
    bool end()
    {
        return(head = NULL);
    }
    void clear();             /* метод просто удаляет все элементы из списка */
    T& operator[](int index); /* перегрузка оператора. В параметрах - индекс (номер элемента) */
    friend ostream& operator<< (ostream& out, const List& list);
    
    
 
    void push_front(T data);        /* метод добавляет элемент в начало списка*/
    void pop_back();                /* удаляет элемент из конца списка */
    void insert(T data, int index); /* вставляет элемент по конкретному индексу */
    
    /* value - данные, index - индекс, по которому эти данные вставлены */
    void removeAt(int index);       /* удаляет элемент из списка по указанному индексу */
 
private:
    template <typename T> /* шаблон */
    class Node              /* вложенный класс (Node - узел) */
    {
    public:                 /* здесь уже все поля можно сделать public к, т.к. сам класс private */
        Node* pNext;        /* (pNext - pointer Next) - указатель на следующий элемент */
        T data;
        
        Node (T data = T(), Node* pNext = nullptr) /* конструктор для класса "Узел". nullptr - нулевой адрес*/
        {
            this->data = data;
            this->pNext = pNext;
        }
    };
 
    int Size; /* кол-во элементов в списке */
    Node <T>* head; /* указатель, так как все элементы одн. списка выделяются в динамич. памяти */
public:
    List& operator ++ ()
    {
        head = head->pNext;
        return *this;
    }
};
 
template <typename T>
List<T>::List() /* реализация конструктора */
{
    Size = 0;
    head = nullptr; /* список пуст */
}
 
template <typename T>
List<T>::~List() /*реализация деструктора*/
{
    cout << "Вызвался деструктор" << endl;
    clear();
}
 
template<typename T>
void List<T>::pop_front()
{
    Node<T>* temp = head; /* temp - временная переменная, хранящая адрес нулевого элемента списка */
    head = head->pNext; /* в head запишем адрес следующего элемента, который идёт за head'ом */
    delete temp; /* temp указывает на те данные, которые были нашим head'ом */
    Size--; /* так как мы удалили один из элементов, число элементов надо понизить на 1 */
}
 
template<typename T>
void List<T>::push_back(T data) /* к слову, мне программа помогла реализовать этот метод*/
{
    if (head == nullptr) /* проверяем на равенство head на ноль */
    {
        head = new Node<T>(data);
    }
    else
    {
        Node<T>* current = this->head; /*current (текущий) - временный объект*/
        while (current->pNext != nullptr)
        {
            current = current->pNext;
        }
        current->pNext = new Node<T>(data);
    }
    Size++;
}
 
template<typename T>
void List<T>::clear() /* метод просто удаляет все элементы из списка */
{
    while (Size) /*Size > 0, while == TRUE, Size = 0, while == FALSE (выход из цикла, если FALSE)*/
    {
        pop_front();
    }
}
 
template<typename T>
T& List<T>::operator[](int index)
{
    int counter = 0;
    Node<T>* current = this->head; /* current отвечает за нахождение в конкретном элементе */
    while (current != nullptr)     /* цикл работает до тех пор, пока current не станет указывать на ноль */
    {                          
        if (counter == index)      /* если ноль - мы в конце списка */
        {
            return current->data;  /* у текущего элемента заберём данные из поля data */
        }
        current = current->pNext;
        counter++;
    }
}
 
 
template<typename T>
void List<T>::push_front(T data)
{
    head = new Node<T>(data, head); /* переносим "голову" в адрес другого элемента */
    Size++;
}
 
template<typename T>
void List<T>::pop_back() /* удаляем последний элемент списка */
{
    removeAt(Size - 1); /* нумерация начинается с нуля. Допустим у нас элементы с инд. 0,1,2 - всего их три */
} /* чтобы получить доступ к последнему - просто
вычитаем единицу */
 
template<typename T>
void List<T>::insert(T data, int index)
{
    if (index == 0) /* если index = 0 */
    {
        push_front(data);
    }
    else
    {
        Node<T>* previous = this->head; /* previous - временный указатель */
 
        for (int i = 0; i < index - 1; i++) /* цикл находит элемент с индексом, предшествующим (int index) */
        { /* на место которого мы хотим поместить объект */
            previous = previous->pNext; /* "-1" означает "предыдущий", как и слово previous */
        } /*в этом цикле мы просто перебираем элементы, идущие по цепочке в списке*/
 
        Node<T>* newNode = new Node<T>(data, previous->pNext); /* объект указывает на след. объект */
        previous->pNext = newNode; /*помещаем наш новый объект по указанному индексу в список */
        /* newMode переменная по факту и не нужна. Это буфер */
        Size++;
    }
 
 
}
 
template<typename T>
void List<T>::removeAt(int index) /* логика примерно такая же, как и с insert, но ориентирована на удаление */
{
    if (index == 0)
    {
        pop_front();
    }
    else
    {
        Node<T>* previous = this->head; /* задача блока кода со 159-й по 163-й строчки - найти предыдущий элемент */
        for (int i = 0; i < index - 1; i++) /* относительно того, который мы хотим удалить */
        {
            previous = previous->pNext;
        }
 
        Node<T>* toDelete = previous->pNext; /* в toDelete лежит адрес старого элемента */
        previous->pNext = toDelete->pNext; /* в тот старый адрес мы помещаем адрес элемента, который мы хотим удалить*/
        delete toDelete; /* удаляем старый адрес */
        Size--; /* уменьшаем число элементов на единицу */
    }
}
 
template<typename T>
ostream& operator<<(ostream& out, const List<T>& list)
{
    for (List<T> i = list; !i.end(); ++i)
    {
        out << list << endl;
    }
    return out;
}
 
int main()
{
    setlocale(LC_ALL, "ru");
 
    List<int> List1;
    cout << "Введите число элементов: ";
    int NumbersCount; /* переменная для числа рандомных значений*/
    cin >> NumbersCount;
 
    for (int i = 0; i < NumbersCount; i++) /* цикл для заполнения списка элементами */
    {
        cout << "Введите объект " <<i+1<<": ";
        int number;
        cin >> number;
        List1.push_back (number); /* втыкаем номер в список */
    }
    
    for (int i = 0; i != NumbersCount; i++)
    {
        cout << List1[i] <<" "; /* вывод элементов списка */
    }
    cout << endl;
    
    /* формирование второго списка */
    List<int> List2;
    int max = 0, index = 0;
 
    for (List<int> i = List1; !i.end(); ++i)
    {                       
        if (max <= List1[i]) /* если макс. элемент меньше элемента по индексу i */
        {
            List2.clear();  /* чистим наш список */
            max = List1[i]; /* мы приравниваем макс. элемент к элементу с индексом  */
            index++;
        }
        
        /* MAX ЭЛЕМЕНТ ОН ПРАВИЛЬНО ОПРЕДЕЛИЛ !!! */
        if (max >= List1[i])
        {
            List2.push_back(index); /* вставляем элемент по опред. индексу. */
        }
    }
 
    ///* если будут одинаковые элементы, он выведет не все их индексы, а только последний... */
 
    cout << endl;
    cout << "Наибольший элемент: " << max << " " << endl;
    cout << "Порядковый номер наибольшего элемента: " << index; /* index определён верно! */
    cout << endl;
 
    cout << List2 << endl;
 
    cout << endl;
    system("pause");
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.10.2022, 20:21
Ответы с готовыми решениями:

Error C2679: бинарный "=": не найден оператор, принимающий правый операнд типа
Сразу скажу что в с++ полный ноль. Но есть потребность решить такую вот задачу: Нужно собрать систему распознавания и слежения за лицами...

Возвращение кортежа - error C2679: бинарный "=": не найден оператор, принимающий правый операнд типа
Привет есть функция, которая возвращает кортеж tuple&lt;X**, Math, int, int, std::vector&lt;std::vector&lt;int&gt;&gt;*&gt; я её...

Ошибка C2679: бинарный '=': не найден оператор, принимающий правый операнд типа 'double'
// ConsoleApplication2.cpp : Defines the entry point for the console application. // #include &quot;stdafx.h&quot; #include &quot;math.h&quot; ...

41
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 00:04  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если перед каждым использовании List::get() проверять на List::end(), то все будет Ок.


Формирование второго списка невозможно без полного анализа первого.
Все промежуточные списки будут временными, пока не завершится анализ.

Например :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<int> List2;
List1.begin();
if (!List1.end()){
   int max = List1.get() , i=1;
   List2.push_front(i);
   ++i;
   for (/*продолжаем*/ List1.next(); !List1.end(); List1.next()){
      if (List1.get() == max)
          List2.push_front(i);
      else if (List1.get() > max){
          List2.clear();
          max = List1.get();
          List2.push_front(i);
      }
      ++i;
   }
}
Добавлено через 6 минут

Если явно не указанно создать самому класс Односвязный Список, тогда зачем вы его велосипедите.
И что значит : нельзя использовать итераторы тогда. Этого в задании нету , но вы это пишите как часть условия.
То есть, задание либо не полное, либо вы выдумываете.
Сейчас объясню. Итераторы нельзя использовать по причине, что их мы на тот момент ещё не проходили, как бы это странно не звучало.
В задании нужно именно с нуля написать класс список и создать два экземпляра этого класса

Добавлено через 2 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если перед каждым использовании List::get() проверять на List::end(), то все будет Ок.


Формирование второго списка невозможно без полного анализа первого.
Все промежуточные списки будут временными, пока не завершится анализ.

Например :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<int> List2;
List1.begin();
if (!List1.end()){
   int max = List1.get() , i=1;
   List2.push_front(i);
   ++i;
   for (/*продолжаем*/ List1.next(); !List1.end(); List1.next()){
      if (List1.get() == max)
          List2.push_front(i);
      else if (List1.get() > max){
          List2.clear();
          max = List1.get();
          List2.push_front(i);
      }
      ++i;
   }
}
Добавлено через 6 минут

Если явно не указанно создать самому класс Односвязный Список, тогда зачем вы его велосипедите.
И что значит : нельзя использовать итераторы тогда. Этого в задании нету , но вы это пишите как часть условия.
То есть, задание либо не полное, либо вы выдумываете.
Ваш мини-итератор, думаю, в принципе может удовлетворять условию, потому что вы его реализовали как просто указатель. Никакой заумной реализации
0
29.10.2022, 00:10

Не по теме:


Не обязательно копировать весь огромный пост, можно выделить фрагмент сообщения, появится всплывающий Хинт "цитировать", нажимаем. цитата появляется в поле быстрого ответа.

0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 00:12  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если перед каждым использовании List::get() проверять на List::end(), то все будет Ок.


Формирование второго списка невозможно без полного анализа первого.
Все промежуточные списки будут временными, пока не завершится анализ.

Например :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<int> List2;
List1.begin();
if (!List1.end()){
   int max = List1.get() , i=1;
   List2.push_front(i);
   ++i;
   for (/*продолжаем*/ List1.next(); !List1.end(); List1.next()){
      if (List1.get() == max)
          List2.push_front(i);
      else if (List1.get() > max){
          List2.clear();
          max = List1.get();
          List2.push_front(i);
      }
      ++i;
   }
}
Добавлено через 6 минут

Если явно не указанно создать самому класс Односвязный Список, тогда зачем вы его велосипедите.
И что значит : нельзя использовать итераторы тогда. Этого в задании нету , но вы это пишите как часть условия.
То есть, задание либо не полное, либо вы выдумываете.
Сейчас объясню. Итераторы мы не можем использовать по той простой причине, что мы на тот момент их ещё не прошли. Но ваш итератор в виде указателя, думаю, удовлетворяет условию.
В задании сказано именно с нуля реализовать класс списка и создать два экземпляра этого класса

Добавлено через 36 секунд
Оки, спасибо большое, буду знать))

Добавлено через 27 секунд
Цитата Сообщение от SmallEvil Посмотреть сообщение

Не по теме:


Не обязательно копировать весь огромный пост, можно выделить фрагмент сообщения, появится всплывающий Хинт "цитировать", нажимаем. цитата появляется в поле быстрого ответа.

Так а я его и не копирую. Я вставлял цитату в ответ
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 11:32  [ТС]
Цитата Сообщение от Nepravilon Посмотреть сообщение
Сейчас объясню. Итераторы нельзя использовать по причине, что их мы на тот момент ещё не проходили, как бы это странно не звучало.
В задании нужно именно с нуля написать класс список и создать два экземпляра этого класса

Добавлено через 2 минуты

Ваш мини-итератор, думаю, в принципе может удовлетворять условию, потому что вы его реализовали как просто указатель. Никакой заумной реализации
Можете, пожалуйста, пояснить, что делает этот цикл?
C++
1
 for (List1.next(); !List1.end(); List1.next())
И почему у нас List1.next() встречается два раза?
0
Заблокирован
29.10.2022, 12:53
Цитата Сообщение от Nepravilon Посмотреть сообщение
Можете, пожалуйста, пояснить, что делает этот цикл?
Стоит начать что вообще делает цикл for.
Он имеет три секции : for(инициализация; условие выхода из цикла; изменение состояния счетчика )
Они все опциональны, необязательны.
Инициализация выполняется один раз, перед первой итерацией цикла и до проверки условия.
Проверка условия - каждый раз перед началом цикла.
Изменения состояния счетчика - каждый раз после выполнения цикла.

Так как мы перед циклом обработали первый элемент списка, то в инициализаторе запросили доступ к следующему (в блоке инициализации).
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 17:49  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Стоит начать что вообще делает цикл for.
Он имеет три секции : for(инициализация; условие выхода из цикла; изменение состояния счетчика )
Они все опциональны, необязательны.
Инициализация выполняется один раз, перед первой итерацией цикла и до проверки условия.
Проверка условия - каждый раз перед началом цикла.
Изменения состояния счетчика - каждый раз после выполнения цикла.

Так как мы перед циклом обработали первый элемент списка, то в инициализаторе запросили доступ к следующему (в блоке инициализации).
Хорошо, с циклом более-менее я разобрался, спасибо

Добавлено через 3 часа 16 минут
Цитата Сообщение от SmallEvil Посмотреть сообщение
Стоит начать что вообще делает цикл for.
Он имеет три секции : for(инициализация; условие выхода из цикла; изменение состояния счетчика )
Они все опциональны, необязательны.
Инициализация выполняется один раз, перед первой итерацией цикла и до проверки условия.
Проверка условия - каждый раз перед началом цикла.
Изменения состояния счетчика - каждый раз после выполнения цикла.

Так как мы перед циклом обработали первый элемент списка, то в инициализаторе запросили доступ к следующему (в блоке инициализации).
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
#include <iostream>
using namespace std;
 
template <class T>
class List
{
    int Size;
    
    struct Node
    {
        T data;
        Node* next;
        Node(const T& data, Node* next = nullptr) : data{ data }, next{ next } {}
    };
 
    Node* it = nullptr; /* наш псевдо-итератор */
    Node* head = nullptr; /* голова списка (начало) */
    Node* list = nullptr; /* указатель на список */
 
public:
 
    List() :list(NULL) /* горе - конструктор */
    {
        cout << "Вызван конструктор листа" << endl;
        return;
    }
 
    bool begin()
    {
        /*cout << "begin:" << endl;*/
        return (it = head);
    }
    T& get()
    {
        /*cout << "get:" << endl;*/
        return it->data;
    }
    void next()
    {
        /*cout << "next:" << endl;*/
        it = it->next;
    }
    bool end()
    {
        /*cout << "end:" << endl;*/
        return it == nullptr;
    }
    void push_front(const T& data)
    {
        /*cout << "push_front:" << endl;*/
        head = new Node(data, head);
    }
    void push_back(const T& data)
    {
        /*cout << "push_back:" << endl;*/
        if (head == nullptr)
        {
            head = new Node(data);
        }
        else
        {
            Node* current = this->head; /* current - временный */
            while (current->next != nullptr)
            {
                current = current->next;
            }
            current->next = new Node(data);
        }
    }
    T pop_front()
    {
        /*cout << "pop front:" << endl;*/
        Node* head = list; 
        list = list->next;
        T data = head->data;
        return data;
    }
 
    bool empty()
    {
        /*cout << "empty:" << endl;*/
        return (list == NULL);
    }
    void clear()     /* метод просто удаляет все элементы из списка */
    {
        /*cout << "clear:" << endl;*/
        while (empty() == false)
        {
            pop_front();
        }
    }
    List& operator ++ ()
    {
        head = head->next;
        return *this;
    }
    T operator * ()
    {
        return head->data;
    }
};
 
int main()
{
    setlocale(LC_ALL, "ru");
 
    List<int> List1;
    cout << "Введите число элементов: ";
    int NumbersCount; /* переменная для числа значений */
    cin >> NumbersCount;
 
    for (int i = 0; i < NumbersCount; i++) /* цикл для заполнения списка элементами */
    {
        cout << "Введите объект " << i + 1 << ": ";
        int number;
        cin >> number;
        List1.push_back(number); /* втыкаем номер в список */
    }
 
    for (List1.begin(); !List1.end(); List1.next())
        cout << List1.get() <<" "; /* вывод элементов списка */
    cout << endl;
    
    /* ФОРМИРОВАНИЕ ВТОРОГО СПИСКА */
    cout << "Формируем второй список" << endl;
    List<int> List2;
    int max = 0, index = 1;
    
 
    for (List<int> it = List1; !it.end(); ++it)
    {
        if (max < *it)
        {
            List2.clear();
            max = *it;
        }
        if (max == *it)
        {
            List2.push_front(index);
        }
        index++;
    }
 
    for (List2.begin(); !List2.end(); List2.next())
        cout << List2.get() << " "; /* вывод элементов списка */
 
    cout << endl;
    return 0;
}
Зря я, наверное, вернулся к истокам первого кода... Тем не менее попытался...
Для себя чисто выводил сообщение, когда отрабатывали методы, чтобы понять, когда и кто запускается
0
Заблокирован
29.10.2022, 18:04
Цитата Сообщение от Nepravilon Посмотреть сообщение
Node* list = nullptr; /* указатель на список */
что это значит ?
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:05  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
что это значит ?
указатель на список. Я нашёл похожий код, там была такая штука
0
Заблокирован
29.10.2022, 18:06
Цитата Сообщение от Nepravilon Посмотреть сообщение
for (List<int> it = List1; !it.end(); ++it)
Опять тоже самое, не понятно что ...
Пора делать
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:09  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Опять тоже самое, не понятно что ...
Пора делать
Так это итератор, которым мы пробегаем список

Добавлено через 27 секунд
Цитата Сообщение от SmallEvil Посмотреть сообщение
Опять тоже самое, не понятно что ...
Пора делать
Я-то могу объяснить где что, но я ещё надеюсь, что хоть кто-то меня наставит на путь истинный XD
Потому что уже мне сложно додумать самостоятельно ((

Я уже на месяц опаздываю со сдачей
0
Заблокирован
29.10.2022, 18:21
Если вы не можете объяснить какую-либо часть кода, вы обязаны ее не использовать.
Нельзя просто брать и копировать части чужого кода.
Каждое действие должно быть чем то обосновано.

У вас есть head, это начало связной цепочки узлов списка.
Зачем нам какой то еще указатель list ?
Про третий указатель it я обосновал зачем он. И да, он там для простоты реализации итерирования списка.

Зачем push_back ? Зачем size ? Зачем оператор ++ ?
Вы с добавлением указателя list, сделали из довольно завершенного класса неработоспособную кашу.
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:23  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если вы не можете объяснить какую-либо часть кода, вы обязаны ее не использовать.
Нельзя просто брать и копировать части чужого кода.
Каждое действие должно быть чем то обосновано.

У вас есть head, это начало связной цепочки узлов списка.
Зачем нам какой то еще указатель list ?
Про третий указатель it я обосновал зачем он. И да, он там для простоты реализации итерирования списка.

Зачем push_back ? Зачем size ? Зачем оператор ++ ?
Вы с добавлением указателя list, сделали из довольно завершенного класса неработоспособную кашу.
1.push_front добавляет элементы в начало, а мне нужно было в конец добавлять
2.size - лишнее, забыл убрать
3.перегрузка, потребовал компилятор

Я сам с этим *list ничего не понял, если честно
0
Заблокирован
29.10.2022, 18:25
Цитата Сообщение от Nepravilon Посмотреть сообщение
Так это итератор
Цитата Сообщение от Nepravilon Посмотреть сообщение
for (List<int> it = List1; !it.end(); ++it)
Нет, в инициализаторе создается копия списка List1, при том полноценной копией ее нельзя назвать.
Так же как и назвать итератором.
List::begin - призван корректно инициализировать внутренний итератор по списку, начиная его с начала.

Добавлено через 1 минуту
Цитата Сообщение от Nepravilon Посмотреть сообщение
а мне нужно было в конец добавлять
Не нужно
Цитата Сообщение от Nepravilon Посмотреть сообщение
3.перегрузка, потребовал компилятор
??? Странно, но у меня компилятор ничего не требует.
Сидит тихонько ждет моих ошибок.

Цитата Сообщение от Nepravilon Посмотреть сообщение
Я сам с этим *list ничего не понял, если честно
Ну так зачем вы его добавили ?
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:27  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Нет, в инициализаторе создается копия списка List1, при том полноценной копией ее нельзя назвать.
Так же как и назвать итератором.
List::begin - призван корректно инициализировать внутренний итератор по списку, начиная его с начала.

Добавлено через 1 минуту

Не нужно

??? Странно, но у меня компилятор ничего не требует.
Сидит тихонько ждет моих ошибок.


Ну так зачем вы его добавили ?
Хорошо, с итератором (копией списка) разобрались. А что насчёт push_back?

Добавлено через 57 секунд
добавил я его по той простой причине, чтобы соответствовать коду, в котором эта штука работает

Добавлено через 16 секунд
Хорошо, перегрузку тоже уберём
0
Заблокирован
29.10.2022, 18:30
Цитата Сообщение от Nepravilon Посмотреть сообщение
а мне нужно было в конец добавлять
Если сильно нужна эта операция, в односвязный список добавляют еще один указатель,
на конец списка,
C++
1
Node * tail.
При этом некоторые методы усложняются, из за дополнительной обработки этого самого указателя.

Добавлено через 2 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если сильно нужна эта операция, в односвязный список добавляют еще один указатель,
на конец списка,
Это не единственная реализация, так же можно возвращать итератор при добавлении в начало списка.
Добавлением метода вставки и последующего усложнения АТД.
Оно вам точно не нужно.
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:50  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Если сильно нужна эта операция, в односвязный список добавляют еще один указатель,
на конец списка,
C++
1
Node * tail.
При этом некоторые методы усложняются, из за дополнительной обработки этого самого указателя.

Добавлено через 2 минуты

Это не единственная реализация, так же можно возвращать итератор при добавлении в начало списка.
Добавлением метода вставки и последующего усложнения АТД.
Оно вам точно не нужно.
Мы же сперва определяем порядковый номер, записываем его во второй список, а затем, если нужно, добавляем ещё номера. Добавлять мы же его в конец должны, чтобы в порядке возрастания их расположить. Так по-людски как-то будет, мне кажется

Добавлено через 15 минут
Цитата Сообщение от Nepravilon Посмотреть сообщение
Мы же сперва определяем порядковый номер, записываем его во второй список, а затем, если нужно, добавляем ещё номера. Добавлять мы же его в конец должны, чтобы в порядке возрастания их расположить. Так по-людски как-то будет, мне кажется
К слову, а с вашей логикой он вообще ничего не выводит

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
#include <iostream>
#include <list>
#include <vector>
 
using namespace std;
 
template <class T>
class List
{
    struct Node
    {
        T data;
        Node* next;
        Node(const T& data, Node* next = nullptr) : data { data }, next { next } {}
    };
 
    Node* it = nullptr; /* наш итератор */
    Node* head = nullptr;
    Node* tail = nullptr;
 
public:
    bool begin()
    {
        return (it = head);
    }
    T& get()
    {
        return it->data;
    }
    void next()
    {
        it = it->next;
    }
    bool end()
    {
        return it == nullptr;
    }
    void push_front(const T& data)
    {
        head = new Node(data, head);
    }
    void push_back(const T& data)
    {
        tail = new Node(data, tail);
    }
    T pop_front()
    {
        /*cout << "pop front:" << endl;*/
        Node* head = it;
        it = it->next;
        T data = head->data;
        return data;
    }
 
    bool empty()
    {
        /*cout << "empty:" << endl;*/
        return (it == NULL);
    }
    void clear()     /* метод просто удаляет все элементы из списка */
    {
        /*cout << "clear:" << endl;*/
        while (empty() == false)
        {
            pop_front();
        }
    }
};
int main()
{
    setlocale(LC_ALL, "ru");
    List<int> List1;
    cout << "Введите число элементов: ";
    int NumbersCount; /* переменная для числа рандомных значений*/
    cin >> NumbersCount;
 
    for (int i = 0; i < NumbersCount; i++) /* цикл для заполнения списка элементами */
    {
        cout << "Введите объект " << i + 1 << ": ";
        int number;
        cin >> number;
        List1.push_back(number); /* втыкаем номер в список */
    }
 
    for (List1.begin(); !List1.end(); List1.next())
        cout << List1.get() << " "; /* вывод элементов списка */
    cout << endl;
 
    /* ФОРМИРОВАНИЕ ВТОРОГО СПИСКА */
    List<int> List2;
    List1.begin();
    
    if (!List1.end()) 
    {
        int max = List1.get(), i = 1;
        List2.push_front(i);
        ++i;
        for ( List1.next(); !List1.end(); List1.next()) 
        {
            if (List1.get() == max)
                List2.push_front(i);
 
            else if (List1.get() > max) 
            {
                List2.clear();
                max = List1.get();
                List2.push_front(i);
            }
            ++i;
        }
    }
 
    for (List2.begin(); !List2.end(); List2.next())
        cout << List2.get() << " "; /* вывод элементов списка */
    cout << endl;
    return 0;
}
0
Заблокирован
29.10.2022, 19:15
Лучший ответ Сообщение было отмечено Nepravilon как решение

Решение

Nepravilon, будете писать мега пупер СПИСОК.
Или с помощью смекалки slim forward list ?

Честно, у меня впервые получился такой странный список.

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
#include <iostream>
 
using namespace std;
template <class T>
class List{
    struct Node{
        T data;
        Node* next;
        Node(const T& data, Node* next = nullptr):data{data}, next{next}{}
    };
    Node* it=nullptr; // наш итератор
    Node* head=nullptr;
    void reset(){
        head = nullptr;
        it = nullptr;
    };
public:
    void clear(){
        Node *h = head;
        Node *tmp;
        while(h){
            tmp = h->next;
            delete h;
            h = tmp;
        }
        reset();
    }
    bool empty(){
        return head == nullptr;
    }
    bool begin(){
        return (it = head);
    }
    T& get(){
        return it->data;
    }
    void next(){
        it = it->next;
    }
    bool end(){
        return it==nullptr;
    }
    void push_front(const T& data){
        head = new Node(data, head);
    }
    void push_after_it(const T& data){
        if (!it)
            begin();
        if (!it){
            head = new Node(data);
            it = head;
            return;
        }
        it->next = new Node(data, it->next);
        next();
    }
    ~List(){
        clear();
    }
};
 
int main()
{
    List<int> l1;
    for(int i=1; i<11; ++i)
       (i%2 != 0) ? l1.push_after_it(i) : l1.push_after_it(100);
    // for manual test find maximum elements
    // status - passed
    // l1.push_after_it(1000);
    // l1.push_after_it(1000);   
    cout << "Original list. \n\"list1\" : " << endl;
    for(l1.begin(); !l1.end(); l1.next())
        cout << l1.get() << ' ';
    cout << endl << endl;
    
    List<int> l2;
    if (l1.begin()){
       int max = l1.get() , i=1;
       l2.push_after_it(i);
       ++i;
       for (/*продолжаем*/ l1.next(); !l1.end(); l1.next()){
          if (l1.get() == max)
              l2.push_after_it(i);
          else if (l1.get() > max){
              l2.clear();
              max = l1.get();
              l2.push_after_it(i);
          }
          ++i;
       }
    }
    
    cout << "List with ordinal numbers of max. elements in \"list1\". \n\"list2\": " << endl;
    for(l2.begin(); !l2.end(); l2.next())
        cout << l2.get() << ' ';
    cout << endl << endl;        
}
Добавлено через 2 минуты
Теперь напишите спецификации/соглашения к своим(моим ) методам.
Так как они не очевидны.
1
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 19:21  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Nepravilon, будете писать мега пупер СПИСОК.
Или с помощью смекалки slim forward list ?

Честно, у меня впервые получился такой странный список.

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
#include <iostream>
 
using namespace std;
template <class T>
class List{
    struct Node{
        T data;
        Node* next;
        Node(const T& data, Node* next = nullptr):data{data}, next{next}{}
    };
    Node* it=nullptr; // наш итератор
    Node* head=nullptr;
    void reset(){
        head = nullptr;
        it = nullptr;
    };
public:
    void clear(){
        Node *h = head;
        Node *tmp;
        while(h){
            tmp = h->next;
            delete h;
            h = tmp;
        }
        reset();
    }
    bool empty(){
        return head == nullptr;
    }
    bool begin(){
        return (it = head);
    }
    T& get(){
        return it->data;
    }
    void next(){
        it = it->next;
    }
    bool end(){
        return it==nullptr;
    }
    void push_front(const T& data){
        head = new Node(data, head);
    }
    void push_after_it(const T& data){
        if (!it)
            begin();
        if (!it){
            head = new Node(data);
            it = head;
            return;
        }
        it->next = new Node(data, it->next);
        next();
    }
    ~List(){
        clear();
    }
};
 
int main()
{
    List<int> l1;
    for(int i=1; i<11; ++i)
       (i%2 != 0) ? l1.push_after_it(i) : l1.push_after_it(100);
    // for manual test find maximum elements
    // status - passed
    // l1.push_after_it(1000);
    // l1.push_after_it(1000);   
    cout << "Original list. \n\"list1\" : " << endl;
    for(l1.begin(); !l1.end(); l1.next())
        cout << l1.get() << ' ';
    cout << endl << endl;
    
    List<int> l2;
    if (l1.begin()){
       int max = l1.get() , i=1;
       l2.push_after_it(i);
       ++i;
       for (/*продолжаем*/ l1.next(); !l1.end(); l1.next()){
          if (l1.get() == max)
              l2.push_after_it(i);
          else if (l1.get() > max){
              l2.clear();
              max = l1.get();
              l2.push_after_it(i);
          }
          ++i;
       }
    }
    
    cout << "List with ordinal numbers of max. elements in \"list1\". \n\"list2\": " << endl;
    for(l2.begin(); !l2.end(); l2.next())
        cout << l2.get() << ' ';
    cout << endl << endl;        
}
Добавлено через 2 минуты
Теперь напишите спецификации/соглашения к своим(моим ) методам.
Так как они не очевидны.
Я просто хотел получить понятную реализацию кода )
Очень надеюсь, что смогу немножко подстроить ваш код под себя!

Спасибо большое

Добавлено через 1 минуту
Цитата Сообщение от SmallEvil Посмотреть сообщение
Nepravilon, будете писать мега пупер СПИСОК.
Или с помощью смекалки slim forward list ?

Честно, у меня впервые получился такой странный список.

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
#include <iostream>
 
using namespace std;
template <class T>
class List{
    struct Node{
        T data;
        Node* next;
        Node(const T& data, Node* next = nullptr):data{data}, next{next}{}
    };
    Node* it=nullptr; // наш итератор
    Node* head=nullptr;
    void reset(){
        head = nullptr;
        it = nullptr;
    };
public:
    void clear(){
        Node *h = head;
        Node *tmp;
        while(h){
            tmp = h->next;
            delete h;
            h = tmp;
        }
        reset();
    }
    bool empty(){
        return head == nullptr;
    }
    bool begin(){
        return (it = head);
    }
    T& get(){
        return it->data;
    }
    void next(){
        it = it->next;
    }
    bool end(){
        return it==nullptr;
    }
    void push_front(const T& data){
        head = new Node(data, head);
    }
    void push_after_it(const T& data){
        if (!it)
            begin();
        if (!it){
            head = new Node(data);
            it = head;
            return;
        }
        it->next = new Node(data, it->next);
        next();
    }
    ~List(){
        clear();
    }
};
 
int main()
{
    List<int> l1;
    for(int i=1; i<11; ++i)
       (i%2 != 0) ? l1.push_after_it(i) : l1.push_after_it(100);
    // for manual test find maximum elements
    // status - passed
    // l1.push_after_it(1000);
    // l1.push_after_it(1000);   
    cout << "Original list. \n\"list1\" : " << endl;
    for(l1.begin(); !l1.end(); l1.next())
        cout << l1.get() << ' ';
    cout << endl << endl;
    
    List<int> l2;
    if (l1.begin()){
       int max = l1.get() , i=1;
       l2.push_after_it(i);
       ++i;
       for (/*продолжаем*/ l1.next(); !l1.end(); l1.next()){
          if (l1.get() == max)
              l2.push_after_it(i);
          else if (l1.get() > max){
              l2.clear();
              max = l1.get();
              l2.push_after_it(i);
          }
          ++i;
       }
    }
    
    cout << "List with ordinal numbers of max. elements in \"list1\". \n\"list2\": " << endl;
    for(l2.begin(); !l2.end(); l2.next())
        cout << l2.get() << ' ';
    cout << endl << endl;        
}
Добавлено через 2 минуты
Теперь напишите спецификации/соглашения к своим(моим ) методам.
Так как они не очевидны.
соглашения?) Не совсем понял, о чём вы.
Пока что я согласен с вашими методами))
0
Заблокирован
29.10.2022, 19:39
Самые важные соглашение :
get() :
*** Методу get() в клиентском коде всегда должен предшествовать проверке конца списка end()
push_after_it() :
* когда итератор (далее ИТР) не инициализирован (1), достиг конца списка (1) или вызываться для пустого списка (3)
вставляемый элемент будет добавлен после :
1,2 - первого элемента
3 - в начало списка
При этом итератор будет установлен на добавленный элемент.

И так далее.
Например для операции удаления, можно установить итератор на какую то валидную позицию.
А можно не устанавливать, если в этом нет необходимости.
Можно просто сбросить в nullptr - неинициализирован.
Это также нужно обдумать и описать.

Заодно разберетесь что да как.
Хоть чуток из всего этого понятно ?
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 19:43  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Самые важные соглашение :
get() :
*** Методу get() в клиентском коде всегда должен предшествовать проверке конца списка end()
push_after_it() :
* когда итератор (далее ИТР) не инициализирован (1), достиг конца списка (1) или вызываться для пустого списка (3)
вставляемый элемент будет добавлен после :
1,2 - первого элемента
3 - в начало списка
При этом итератор будет установлен на добавленный элемент.

И так далее.
Например для операции удаления, можно установить итератор на какую то валидную позицию.
А можно не устанавливать, если в этом нет необходимости.
Можно просто сбросить в nullptr - неинициализирован.
Это также нужно обдумать и описать.

Заодно разберетесь что да как.
Хоть чуток из всего этого понятно ?
метод push_after_it() : - это же по сути аналогия push_back
Удалять пока точно ничего не планируется

Из этого всего мне очень всё понятно, на самом деле, спасибо вам ещё раз огромное, вы меня очень выручили
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.10.2022, 19:43
Помогаю со студенческими работами здесь

Error C2679: бинарный "<<": не найден оператор, принимающий правый операнд типа "std::string" (или приемлемое
эмулятор работы банкомата Например #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;time.h&gt; ...

binary "оператор": не найден оператор, принимающий правый операнд типа "тип" (или приемлемое преобразование отсутствует)
Выдаёт ошибку С2679: бинарный &quot;-&quot; не найден оператор, принимающий правый операнд типа &quot;std::chrono::steady_clock::time_point&quot;(или...

Error C2679: бинарный ">>": не найден оператор, принимающий правый операнд
перелопатил кучу форумов, кругом одно и то же - якобы вставь библиотеку и будет счастье. раньше работало нормально. могут ли сторонние...

Error C2679: бинарный "=": не найден оператор, принимающий правый операнд
Ошибка 1 error C2679: бинарный &quot;=&quot;: не найден оператор, принимающий правый операнд типа...

Ошибка C2679 бинарный "<<": не найден оператор, принимающий правый операнд типа
void SerializeInstitute(ofstream&amp; fileStream, Institute imi) { fileStream &lt;&lt; &quot;Course{\n&quot; &lt;&lt; endl &lt;&lt; &quot;Students: &quot; &lt;&lt;...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
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? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru