Bonjour à tous,

Je suis en train de m'amuser () avec les template C++. Je souhaite définir un type de mapping différent du std::map par le biais d'un template et de créer également un Iterator spécifique suivant le Design Pattern du GoF. Pour cela, je souhaite ajouter une méthode à mon mapping qui permette de retourner un pointeur sur un itérateur.

Tout est dans un fichier unique et voici le début avec le premier patron de classe:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#ifndef DICT_H
#define DICT_H
 
#include <map>
 
template <typename K, typename V>
class Dict
{
    public:
    Dict();
    ~Dict();
    bool hasKey(K);
    void set(K, V);
    V get(K);
    DictIterator<K,V>* createIterator();
 
    private:
    std::map<K,V> items;
};
 
template <typename K, typename V>
Dict<K,V>::Dict()
{}
 
template <typename K, typename V>
Dict<K,V>::~Dict()
{}
 
template <typename K, typename V>
bool Dict<K,V>::hasKey(K key)
{
    return items.find(key) != items.end();
}
 
template <typename K, typename V>
void Dict<K,V>::set(K key, V value)
{
    items[key] = value;
}
 
template <typename K, typename V>
V Dict<K,V>::get(K key)
{
    if (hasKey(key))
        return items[key];
    else
        throw KeyError(obj2str(key), "V Dict<K,V>::get(K key)", "dict.hpp", 47);        
}
 
template <typename K, typename V>
DictIterator<K,V>* Dict<K,V>::createIterator()
{
    DictIterator<K,V> *it = new DictIterator();
    return it;
}
et voici la fin du fichier avec le deuxième patron (l'iterateur):

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
template <typename K, typename V>
class DictIterator
{
    public:
    DictIterator(Dict<K,V> *dict);
    ~DictIterator();
    void first();
    void last();
    void next();
    void previous();
    bool isDone();
    std::pair<K,V> current();
 
    private:
    typename std::map<K, V>::iterator  pos;
    Dict<K,V> *dict;
};
 
template <typename K, typename V>
DictIterator<K,V>::DictIterator(Dict<K,V> *dict): dict(dict), 
                                                  pos(dict->begin()) 
{}
 
template <typename K, typename V>
DictIterator<K,V>::~DictIterator() {}
 
template <typename K, typename V>
void DictIterator<K,V>::first()
{
    pos = dict->begin();
}
 
template <typename K, typename V>
void DictIterator<K,V>::last()
{
    pos = dict->end();
}
 
template <typename K, typename V>
void DictIterator<K,V>::next()
{
    pos++;
}
 
template <typename K, typename V>
void DictIterator<K,V>::previous()
{
    pos--;
}
 
template <typename K, typename V>
bool DictIterator<K,V>::isDone()
{
    return pos == dict->end();
}
 
template <typename K, typename V>
std::pair<K,V> DictIterator<K,V>::current()
{
    return *pos;
}
 
#endif
J'ai un beau message d'erreur à la compil:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
src/c++/lib/include/dict.hpp:18: error: ISO C++ forbids declaration of ‘DictIterator’ with no type
src/c++/lib/include/dict.hpp:18: error: expected ‘;’ before ‘<’ token
src/c++/lib/include/dict.hpp:56: error: expected constructor, destructor, or type conversion before ‘<’ token
error: command 'gcc' failed with exit status 1
make: *** [all] Erreur 1
comme je ne présente qu'une partie des méthodes, les numéros de ligne ne correspondent pas forcément.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
src/c++/lib/include/dict.hpp:18: error: ISO C++ forbids declaration of ‘DictIterator’ with no type
me ramène à la ligne:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
DictIterator<K,V>* createIterator();
qui correspond à la déclaration de la méthode.

et

Code : Sélectionner tout - Visualiser dans une fenêtre à part
src/c++/lib/include/dict.hpp:56: error: expected constructor, destructor, or type conversion before ‘<’ token
à la ligne:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
template <typename K, typename V>
DictIterator<K,V>* Dict<K,V>::createIterator()
qui correspond à la définition.

A vrai dire, je ne vois pas trop ce que je fais de mal. Je comprends que mon compilateur me jette car il ne reconnait pas DictIterator<K,V> comme un type mais je ne sais pas comment y remédier.

Comme je débute en c++, n'hésitez pas à me faire des remarques d'ordre général sur le code.

Merci pour votre aide.

kango