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

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

28.10.2022, 20:21. Показов 2270. Ответов 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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
29.10.2022, 18:04
Цитата Сообщение от Nepravilon Посмотреть сообщение
Node* list = nullptr; /* указатель на список */
что это значит ?
0
2 / 2 / 0
Регистрация: 12.06.2022
Сообщений: 175
29.10.2022, 18:05  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
что это значит ?
указатель на список. Я нашёл похожий код, там была такая штука
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
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
Ответ Создать тему
Новые блоги и статьи
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
[golang] Worker Pool
alhaos 09.06.2026
Worker Pool Worker Pool — паттерн конкурентной обработки задач в Go. Суть: фиксированное количество горутин-воркеров читают задачи из общего канала и пишут результаты в общий канал результатов. . . .
[golang] Pipeline
alhaos 08.06.2026
Pipeline Pipeline — паттерн конкурентной обработки данных в Go. Суть: данные проходят через цепочку независимых стадий, каждая из которых работает в своей горутине и общается с соседями через. . .
Свет внутри себя
kumehtar 07.06.2026
Пусть это будет здесь lIs4oanZS9Y
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru