Форум программистов, компьютерный форум CyberForum.ru

Создание шаблона - C++

Восстановить пароль Регистрация
 
Jelum
0 / 0 / 0
Регистрация: 30.05.2010
Сообщений: 17
23.05.2012, 00:41     Создание шаблона #1
Задача - сделать шаблон контейнера. То до чего додумался:

templates.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "stdafx.h"
 
#ifndef _TEMPL_H
#define _TEMPL_H
 
template<class T> 
class LinkedList{
    struct Node{
        T *data;
        Node *next, *prev;
        Node(T* dat, Node* nxt, Node* prv)
            : data(dat), next(nxt), prev(prv) {};
        Node()
            : data(0), next(0), prev(0) {};
        } *node;
    int size;
 
    LinkedList(const LinkedList&) {};
public:
    // constr
    LinkedList() : size(0), node(0) {};
    ~LinkedList();
 
    //iterator
    class iterator;
    friend class iterator;
    class iterator{
        Node *ptr;
    public:
        // constr
        iterator(); // end
        iterator(const iterator&); // special position
        iterator(const LinkedList&); // begin
 
        // operators
        bool operator++ ();
        bool operator++ (int);
        bool operator-- ();
        bool operator-- (int);
        bool operator== (const iterator&);
        bool operator!= (const iterator&);
 
        // funcs
        T* current();
        };
 
    // funcs
    bool add(T*);
    bool isEmpty();
    bool reset();
    bool remove(iterator&);
    bool remove_back();
    T* show(const iterator&);
 
    iterator begin();
    iterator end();
    };
 
#endif // _TEMPL_H


template.cpp

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
#include "stdafx.h"
 
 
#include <iostream>
#include "template.h"
 
// iterator
 
// end
template<class T> 
LinkedList<T>::iterator::iterator(){
    ptr = 0;
    };
 
// special position
template<class T> 
LinkedList<T>::iterator::iterator(const iterator& org){
    ptr = org.ptr;
    };
 
// begin
template<class T>
LinkedList<T>::iterator::iterator(const LinkedList& org){
    ptr = org.node;
    };
 
// operators
template<class T> bool LinkedList<T>::iterator::operator++ (){
    if(ptr->next){
        ptr = ptr->next;
        return 1;
        }
    return 0;
    };
template<class T> bool LinkedList<T>::iterator::operator++ (int){
    return operator++;
    };
 
template<class T> bool LinkedList<T>::iterator::operator-- (){
    if(ptr->prev){
        ptr = ptr->prev;
        return 1;
        }
    return 0;
    };
template<class T> bool LinkedList<T>::iterator::operator-- (int){
    return operator--;
    };
 
template<class T> 
bool LinkedList<T>::iterator::operator== (const iterator& org){
    (org.ptr == ptr)? return 1: return 0;
    };
template<class T> 
bool LinkedList<T>::iterator::operator!= (const iterator& org){
    return !(operator== (org));
    };
 
template<class T> T* LinkedList<T>::iterator::current(){
    return ptr->data;
    };
 
// LinkedList
template<class T> LinkedList<T>::~LinkedList(){
    reset();
    delete node;
    node = 0;
    };
 
template<class T> bool LinkedList<T>::add(T* dat){
    node = new (std::nothrow) Node(dat,node,0);
    if(node){
        node->next->prev = node;
        size++;
        return 1;
        }
    return 0;
    };
 
template<class T> bool LinkedList<T>::isEmpty(){
    return (size? 0: 1);
    };
 
template<class T> bool LinkedList<T>::reset(){
    while(remove_back());
    if(size)
        return 0;
    return 1;
    };
 
template<class T> bool LinkedList<T>::remove(iterator& ind){
    Node *tmp;
    tmp = ind.ptr;
 
    if(!tmp)
        return 0;
 
    if(tmp->prev){
        ind--;
        tmp->prev->next = tmp->next;
        }
    if(tmp->next){
        tmp->next->prev = tmp->prev;
        ind++;
        }
    delete tmp;
    tmp = 0;
    return 1;
    };
 
template<class T> bool LinkedList<T>::remove_back(){
    Node *ptr;
    ptr = node;
    if(ptr){ // if list has any elem
        while(ptr->next)
            ptr = ptr->next;
        ptr = ptr->prev;
        delete ptr->next;
        ptr->netx = 0;
        return 1;
        }
    return 0; // nothing to delete
    };
 
template<class T> T* LinkedList<T>::show(const iterator& ind){
    iterator tmp(ind);
    return tmp.current();
    };
 
template<class T> LinkedList<T>::iterator LinkedList<T>::begin(){
    return iterator(*this);
    };
 
template<class T> LinkedList<T>::iterator LinkedList<T>::end(){
    iterator tmp(*this);
    while(tmp++);
    return tmp;
    };


ошибки visual studio

Warning 1 warning C4346: 'LinkedList<T>::iterator' : dependent name is not a type c:\oop\ex5\ex5\template.cpp 130
Error 2 error C2143: syntax error : missing ';' before 'LinkedList<T>::begin' c:\oop\ex5\ex5\template.cpp 130
Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\oop\ex5\ex5\template.cpp 130
Error 4 error C1903: unable to recover from previous error(s); stopping compilation c:\oop\ex5\ex5\template.cpp 130

строка 130 - template<class T> LinkedList<T>::iterator LinkedList<T>::begin(){



как написать правильнее, как исправить ошибки

Добавлено через 12 часов 59 минут
вопрос до сих пор актуален
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
23.05.2012, 00:54     Создание шаблона #2
вообще шаблоны не реализуются в c++ файлах. все в h файле.
по быстрому это можно исправить, написав в конце h файла
#include "template.cpp"
по хорошему все нужно в h файл перетащить.

Warning 1 warning C4346: 'LinkedList<T>::iterator' : dependent name is not a type c:\oop\ex5\ex5\template.cpp 130
нужно писать typename LinkedList<T>::iterator

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

вот я проверил. похоже что так и есть. typename проставте где надо.
Jelum
0 / 0 / 0
Регистрация: 30.05.2010
Сообщений: 17
23.05.2012, 01:06  [ТС]     Создание шаблона #3
Цитата Сообщение от DU Посмотреть сообщение
вообще шаблоны не реализуются в c++ файлах. все в h файле.
по быстрому это можно исправить, написав в конце h файла
#include "template.cpp"
по хорошему все нужно в h файл перетащить.

Warning 1 warning C4346: 'LinkedList<T>::iterator' : dependent name is not a type c:\oop\ex5\ex5\template.cpp 130
нужно писать typename LinkedList<T>::iterator

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

вот я проверил. похоже что так и есть. typename проставте где надо.
Да, я перенёс с h файл и вставил typename - компилятор собрал. Завтра буду тестировать на "рабочесть"
Ты мог бы в двух словах объяснить смысл typename. я уже прочёл что это, но в Экеле всё работало без него (может быть из-за того, что определения были в самом классе, а не после него). его употребляют только в похожих на мой случаях?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
23.05.2012, 16:56     Создание шаблона #4
нужно смотреть в сторону зависимых имен типов в шаблонах.
вот тут вроде кое-что написано:
http://tortuga.angarsk.su/fb2/myerss..._C.fb2_20.html

...

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

template <typename C> // печатает второй элемент контейнера
void print2nd(const C& container) // это некорректный C++!
{
C::const_iterator *x;
...
}

Выглядит так, будто мы объявили x как локальную переменную – указатель на C::const_iterator. Но это только видимость, поскольку мы «знаем», что C::const_iterator является типом. А что, если в классе C есть статический член данных по имени const_iterator и что, если x будет именем глобальной переменной? В этом случае приведенный код не будет объявлять локальную переменную, а окажется умножением C::const_iterator на x! Звучит невероятно, но это возможно, и авторы синтаксических анализаторов исходного кода на C++ должны позаботиться обо всех возможных вариантах входных данных, даже самых сумасшедших.
Пока о C ничего не известно, мы не можем узнать, является ли C::const_iterator типом или нет, а во время разбора шаблона print2nd компилятор ничего о C не знает. В C++ предусмотрено правило, разрешающее эту неопределенность: если синтаксический анализатор встречает вложенное зависимое имя в шаблоне, он предполагает, что это не имя типа, если только вы не укажете это явно. По умолчанию вложенные зависимые имена не являются типами. Есть исключение из этого правила, о котором я расскажу чуть ниже.
Имея это в виду, посмотрите опять на начало print2nd:

template <typename C>
void print2nd(const C& container)
{
if (container.size() >= 2) {
C::const_iterator iter(container.begin()); // предполагается, что
... // это не имя типа

Теперь должно быть ясно, почему это некорректный C++. Объявление iter имеет смысл только в случае, если C::const_iterator является типом, но мы не сообщили C++ об этом, потому C++ предполагает, что это не так. Чтобы исправить ситуацию, мы должны сообщить C++, что C::const_iterator – это тип. Для этого мы помещаем ключевое слово typename непосредственно перед ним:

template <typename C> // это корректный С++
void print2nd(const C& container)
{
if (container.size() >= 2) {
typename C::const_iterator iter(container.begin());
...
}
}

Общее правило просто: всякий раз, когда вы обращаетесь к вложенному зависимому имени в шаблоне, вы должны предварить его словом typename (скоро я опишу исключение).

...
Yandex
Объявления
23.05.2012, 16:56     Создание шаблона
Ответ Создать тему
Опции темы

Текущее время: 12:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru