1 / 1 / 0
Регистрация: 06.02.2012
Сообщений: 31

Не могу найти ошибку.

18.02.2012, 13:57. Показов 727. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день всем! Опять у меня проблемы с моими "любимыми" шаблонами. Есть две шаблонные функции печатающие содержимое списка. Первая для любого типа, вторая для char. В ней возникают такие ошибки:

15/15-06/List.h||In member function ‘void List<T>:rintList() const [with T = char]’:|
15/15-06/List.h|97|error: invalid use of incomplete type ‘struct ListNode<char>’|
15/15-06/List.h|5|error: declaration of ‘struct ListNode<char>’|
15/15-06/List.h|98|error: invalid use of incomplete type ‘struct ListNode<char>’|
15/15-06/List.h|5|error: declaration of ‘struct ListNode<char>’|
||=== Build finished: 4 errors, 0 warnings ===|


Вот код классов и этих функций:

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
template<typename T> //строка номер 5 на которую жалуется компилятор
class ListNode;
 
template<typename T>
class List
{
    public:
        List();//
        ~List();//
        void inputFirst(const T &);//
        void deleteFirst();
        void inputLast(const T &);//
        void deleteLast();
        bool isEmpty() const;//
        void printList()const;//
        List<T> & operator=(const List<T> &);
        List<T> & operator+(const List<T> &);
 
    private:
        ListNode<T> *first;
        ListNode<T> *last;
        ListNode<T> *newNode(const T &);//
};
 
template<typename T>
class ListNode
{
    friend class List<T>;
 
    public:
        ListNode()
        {
            next = NULL;
        };
 
    private:
        ListNode *next;
        T data;
};
 
template<>
void List<char>::printList() const
{
    if(isEmpty())
    {
        cout << "List is empty" << endl;
        return;
    }
 
    ListNode<char> *ptr = first;
 
    while(ptr != NULL)
    {
        cout << ptr->data;//строка 97 на которую жалуется компилятор
        ptr = ptr->next;//строка 98 на которую жалуется компилятор
    }
    cout << endl;
}
 
 
template<typename T>
void List<T>::printList() const
{
    if(isEmpty())
    {
        cout << "List is empty" << endl;
        return;
    }
 
    ListNode<T> *ptr = first;
 
    while(ptr != NULL)
    {
        cout << ptr->data << endl;
        ptr = ptr->next;
    }
}
Пожалуйста помогите вычислить ошибку.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.02.2012, 13:57
Ответы с готовыми решениями:

Найти слова, повторяющиеся более одного раза, не могу найти ошибку
#include &lt;iostream&gt; using namespace std; void obr1(char **s, char **mas, int n, int m) { int i; int k; char *tm; for(i...

Массивы. Посчитать количество положительных, найти минимальное, удалить строку с минимальным (Не могу найти ошибку)
// Заданы матрицы X(8;4),Y(5;5),Z(6;9). // Для каждой из матриц определить строку, в которой находится наименьшее // количество...

Не могу найти ошибку
Здравствуйте,столкнулся с такой проблемой ,нужно было написать программу,которая определяет количество элементов,которые находятся в...

7
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
18.02.2012, 14:19
Лучше сделать ListNode внутренним классом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<typename T>
class List
{
    class ListNode
    {
        friend class List<T>;
        public:
            ListNode(): next(0) {}
        private:
            ListNode *next;
            T data;
    };
 
    public:
        void printList()const;
 
    private:
        ListNode *first, *last;
        ListNode* newNode(const T &);
};
0
1 / 1 / 0
Регистрация: 06.02.2012
Сообщений: 31
18.02.2012, 19:58  [ТС]
Лучше, но я как то не понял про конструктор
C++
1
ListNode(): next(0) {}
как это?

Так как то тоже много ошибок вылезает. А если не делать ListNode внутренним классом? Ошибка то наверняка очень просто исправляется, я так думаю...
0
3 / 26 / 9
Регистрация: 29.08.2010
Сообщений: 204
18.02.2012, 20:58
eaglecrazy,
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
#include <iostream>
 
using namespace std; 
//template<typename T> //строка номер 5 на которую жалуется компилятор
//class ListNode;
 
 
 
template<typename T>
class ListNode {
 //  friend class List<T>;
 
    public:
        ListNode()
        {
            next = NULL;
        };
 
        T getData() {
            return data;
        }
        
        ListNode* getNext() {
            return next;
        }
public:
 
        ListNode *next;
        T data;
};
 
 
template<typename T>
class List
{
    public:
        List() {};//
        ~List() {};//
        void inputFirst(const T &);//
        void deleteFirst();
        void inputLast(const T &);//
        void deleteLast();
        bool isEmpty() const;//
        void printList()const;//
    void printList2(char = 0)const {
        if(this->isEmpty()){
                cout << "List is empty" << endl;
                 return;
            }
 
            ListNode<char> *ptr = first;
 
            while(ptr != NULL)
            {
                cout << ptr->data;//строка 97 на которую жалуется компилятор
                ptr = ptr->next;//строка 98 на которую жалуется компилятор
            }
            cout << endl;
        }
 
        List<T> & operator=(const List<T>&);
        List<T> & operator+(const List<T> &);
 
    private:
        ListNode<T> *first;
        ListNode<T> *last;
        ListNode<T> *newNode(const T &);//
};
 
 
 
template<typename T>
void List<T>::printList() const
{
    if(this->isEmpty())
    {
        cout << "List is empty" << endl;
        return;
    }
 
    ListNode<T> *ptr = first;
 
    while(ptr != NULL)
    {
        cout << ptr->data << endl;
        ptr = ptr->next;
    }
}
Так не пойдет? Понятно что это сырой вариант
я привык всегда реализовывать функции в классе)

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
#include <iostream>
 
class out_of_range : public std::exception {
 
public:
    out_of_range() { }
};
 
template<class Node, class T>
class iterator {
    
private:
    Node *current;
    
public:
    iterator(Node *node):current(node) { }
    
    void operator++() {
 
        if(!current)
            throw new out_of_range();
 
        current = current->getNext();
    }
 
    bool operator == (iterator const &other) {
 
        return current == other.current;
    }
 
    bool operator !=(iterator const &other) {
        
        return current != other.current;
    }
 
    Node* operator->() {
 
        return current;
    }
};
 
 
template<class T>
class node {
 
private:
    T value;
    node *next;
    node *prev;
public:
    node(T value) {
        next = NULL;
        prev = NULL;
        this->value = value;
    }
 
    node* getNext() {
        return next;
    }
 
    node* getPrev() {
        return prev;
    }
 
    void setPrev(node *n) {
        prev = n;
    }
    void setNext(node *n) {
        next = n;
    }
    T getValue() {
        return value;
    }
};
        
template<class T> 
class list {
 
public:
    typedef iterator<node<T>, T> iterator;
 
private:
    node<T> *root;
 
public:
    list():root(NULL) { };
 
    void push_back(T value) {
 
        if(root) {
 
            node<T> *temp = root;
            while(temp->getNext()) {
                temp = temp->getNext();
            }
            temp->setNext(new node<T>(value));
            temp->getNext()->setPrev(temp);
 
        }else {
            root = new node<T>(value);
        }
 
    }
    
    T pop_back() {
 
        if(!root) 
            throw new out_of_range();
 
        if(!root->getNext()) {
            T value = root->getValue();
            delete root;
            root = NULL;
            return value;
        } else {
 
            node<T> *del = root;
            while(del->getNext()) {
                del = del->getNext();
            }
 
            T value = del->getValue();
            del->getPrev()->setNext(NULL);
            delete del;
            return value;
        }
    }
 
    void push_front(T value) {
 
        if(!root) {
            root = new node<T>(value);
        } else {
 
            node<T> *newnode = new node<T>(value);
            newnode->setNext(root);
            root->setPrev(newnode);
            root = newnode;
        }
    }
 
    T pop_front() {
 
        if(!root) 
            throw new out_of_range();
 
        if(!root->getNext()) {
            T value = root->getValue();
            delete root;
            root = NULL;
            return value;
        }else {
 
            T value = root->getValue();
            node<T> *newroot = root->getNext();
            delete root;
            root = newroot;
            root->setPrev(NULL);
            return value;
        }
    }
 
        
    iterator begin() {
 
        return iterator(root);
    }
 
    iterator end() {
        return iterator(NULL);
    }
 
    ~list() {
 
        while(root) {
 
            node<T> *del = root;
            root = root->getNext();
            delete del;
        
        }
    }
 
};
 
 
 void main() {
 
 
    list<int> integer;
 
    integer.push_back(1);
    integer.push_back(2);
    integer.push_back(3);
    integer.push_back(4);
    integer.push_front(5);
    integer.push_front(6);
 
    std::cout << integer.pop_back() << std::endl;
    std::cout << integer.pop_back() << std::endl;
    std::cout << integer.pop_front() << std::endl;
    std::cout << integer.pop_back() << std::endl;
    std::cout << integer.pop_back() << std::endl;
    
 
    for(list<int>::iterator it = integer.begin(); it != integer.end(); it++)
        std::cout << it->getValue() << std::endl;
 
}
я тоже пытался делать свой лист может поможет
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
template<>
void List<char>::printList() const
{
    if(isEmpty())
    {
        cout << "List is empty" << endl;
        return;
    }
 
    ListNode<char> *ptr = first;
 
    while(ptr != NULL)
    {
        cout << ptr->data;//строка 97 на которую жалуется компилятор
        ptr = ptr->next;//строка 98 на которую жалуется компилятор
    }
    cout << endl;
}
 
 
template<typename T>
void List<T>::printList() const
{
    if(isEmpty())
    {
        cout << "List is empty" << endl;
        return;
    }
 
    ListNode<T> *ptr = first;
 
    while(ptr != NULL)
    {
        cout << ptr->data << endl;
        ptr = ptr->next;
    }
}
по моему функции так не перегружаются, должны отличатся типами параметров.
Даже не понятно зачем тебе такая функция если первая тоже самое
0
1 / 1 / 0
Регистрация: 06.02.2012
Сообщений: 31
18.02.2012, 22:04  [ТС]
Цитата Сообщение от HardMorg Посмотреть сообщение
Так не пойдет? Понятно что это сырой вариант
Попробую без дружественного класса сделать. Но всё же очень хотелось бы понять, почему так не работает...


Цитата Сообщение от HardMorg Посмотреть сообщение
я тоже пытался делать свой лист может поможет
Спасибо. Разбираться с чужим кодом... мне бы со своим разобраться



Цитата Сообщение от HardMorg Посмотреть сообщение
по моему функции так не перегружаются, должны отличатся типами параметров.
Даже не понятно зачем тебе такая функция если первая тоже самое
Ну одна функция элемент класса List<T>, другая List<char>, это две большие разницы насколько я понимаю. А функция для List<char> должна печатать строчки, вместо того что бы печатать всё остальное в столбик. Вот.

Добавлено через 23 минуты
Вот я избавился от дружественности, всё заработало. Но хотелось бы разобраться, почему не работает так, как я написал изначально???
0
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
18.02.2012, 22:10
Цитата Сообщение от eaglecrazy Посмотреть сообщение
template<typename T> //строка номер 5 на которую жалуется компилятор
class ListNode;
а самое простое пробовал? вынести все определение листноды над лист?

в общем на самый верх просто определение

C++
1
template<typename T> class List;
это чтобы в листноде не ругалось на friend.

далее полное определение листноды, и только потом сам лист

по идее логика такова. в листе у тебя активно используется листнода с ее членами. вот он и ругается, что мол не полная она,
мало просто прототипа наверху.

а в самой листноде просто прописано, мол класс лист - друг. и все никакого использования.
поэтому на самый верх объявление прототипа листа, далее полное определение листноды, потом лист

попробуй
1
3 / 26 / 9
Регистрация: 29.08.2010
Сообщений: 204
18.02.2012, 22:17
eaglecrazy,
как по моему просто ты не пергрузил функции вот и все, сам подумай вот шаблон который принимает любой тип и даже чар, то есть я не могу обьяснить, ну а как тогда описать эти 2 методы внутри в классе что бы была перегрузка?)))
0
1 / 1 / 0
Регистрация: 06.02.2012
Сообщений: 31
18.02.2012, 22:33  [ТС]
Цитата Сообщение от AzaKendler Посмотреть сообщение
а самое простое пробовал? вынести все определение листноды над лист?
Попробовал, вставил, подключил листноду перед листом и всё заработало! Ура-ура! Огромное спасибо!

Теперь двумя способами сделал -> польза мне


Цитата Сообщение от HardMorg Посмотреть сообщение
ну а как тогда описать эти 2 методы внутри в классе что бы была перегрузка?)))
Незнаю :/ Наверно поэтому лучше такие вещи вне класса записывать, явно указывая для какого класса эта функция.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.02.2012, 22:33
Помогаю со студенческими работами здесь

Не могу найти ошибку
#include &lt;iostream&gt; #include &lt;cmath&gt; #define N = 3 using namespace std; void vvodMatr(int a, int n) int poiskMax (int a, int n) ...

Не могу найти ошибку
Добрый день, вот простенькая задача: &quot;В одном шаге от счастья&quot; Вова купил билет в трамвае 13-го маршрута и сразу посчитал суммы...

Не могу найти ошибку
Составить программу, в которой описывается структура из полей: Товар, Цена, Сорт. Организовать ввод двух структурных переменных, вывод...

Не могу найти ошибку
Задание: Уплотнить заданную матрицу, удаляя из нее строки и столбцы, заполненные нулями. Найти номер первой из строк, содержащих хотя бы...

не могу найти ошибку!
почему в typePlane вместо значения, которое вводит пользователь, выводит какое-то большое значение из цифр и букв? ...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

Новые блоги и статьи
Исследование рантаймов контейнеров Docker, containerd и rkt
Mr. Docker 11.05.2025
Когда мы говорим о контейнерных рантаймах, мы обсуждаем программные компоненты, отвечающие за исполнение контейнеризованных приложений. Это тот слой, который берет образ контейнера и превращает его в. . .
Micronaut и GraalVM - будущее микросервисов на Java?
Javaican 11.05.2025
Облачные вычисления безжалостно обнажили ахиллесову пяту Java — прожорливость к ресурсам и медлительный старт приложений. Традиционные фреймворки, годами радовавшие корпоративных разработчиков своей. . .
Инфраструктура как код на C#
stackOverflow 11.05.2025
IaC — это управление и развертывание инфраструктуры через машиночитаемые файлы определений, а не через физическую настройку оборудования или интерактивные инструменты. Представьте: все ваши серверы,. . .
Инъекция зависимостей в ASP.NET Core - Практический подход
UnmanagedCoder 11.05.2025
Инъекция зависимостей (Dependency Injection, DI) — это техника программирования, которая кардинально меняет подход к управлению зависимостями в приложениях. Представьте модульный дом, где каждая. . .
Битва за скорость: может ли Java догнать Rust и C++?
Javaican 11.05.2025
Java, с её мантрой "напиши один раз, запускай где угодно", десятилетиями остаётся в тени своих "быстрых" собратьев, когда речь заходит о сырой вычислительной мощи. Rust и C++ традиционно занимают. . .
Упрощение разработки облачной инфраструктуры с Golang
golander 11.05.2025
Причины популярности Go в облачной инфраструктуре просты и одновременно глубоки. Прежде всего — поразительная конкурентность, реализованная через горутины, которые дешевле традиционных потоков в. . .
Создание конвейеров данных ETL с помощью Pandas
AI_Generated 10.05.2025
Помню свой первый опыт работы с большим датасетом — это была катастрофа из неотформатированных CSV-файлов, странных значений NULL и дубликатов, от которых ехала крыша. Тогда я потратил три дня на. . .
C++ и OpenCV - Гайд по продвинутому компьютерному зрению
bytestream 10.05.2025
Компьютерное зрение — одна из тех технологий, которые буквально меняют мир на наших глазах. Если оглянуться на несколько лет назад, то сложно представить, что алгоритмы смогут не просто распознавать. . .
Создаем Web API с Flask и SQLAlchemy
py-thonny 10.05.2025
В веб-разработке Flask и SQLAlchemy — настоящие рок-звезды бэкенда, особенно когда речь заходит о создании масштабируемых API. Эта комбинация инструментов прочно закрепилась в арсенале разработчиков. . .
Квантовое будущее для разработчиков: Что необходимо знать сегодня
EggHead 10.05.2025
Квантовые вычисления больше не являются чем-то из области научной фантастики. Пока большинство разработчиков погружены в осваивание очередного JavaScript-фреймворка или изучение новых возможностей. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru