Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Langage
Langage Langage C++, Programmation Orientée Objet, Templates, etc. Avant de poster : FAQ C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 10/12/2012, 12h41   #1
Agoudard
Futur Membre du Club
 
Inscription : avril 2010
Messages : 96
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 96
Points : 17
Points : 17
Par défaut Paramètre template et itérateur de set.

Bonjour,

Dans l'initialisation de ma première boucle "for" (et pas foreach).
Le compilateur m'indique :
Code :
1
2
 
expected ';' before 'kA'
J'ai essayé de retirer l'ensemble du code et de garder uniquement la ligne qui pose problème et j'obtiens toujours la même erreur.

Quelqu'un aurait une idée ?

Code :
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
 
template< class C >
QSet< const QPair< const C*, const C* > > Quadtree< C >::couples() const
{
    QSet< const Quadtree* > kLeaves = leaves();
    QSet< QPair< const C*, const C* > > kCouples;
 
    foreach(const Quadtree* pkLeaf, kLeaves)
    {
        const QSet< const C* >& rkItems = pkLeaf->items();
 
        for(QSet< const C* >::ConstIterator kA = rkItems.begin();
            kA != rkItems.end() && kA + 1 != rkItems.end();
            ++kA)
        {
            for(QSet< const C* >::ConstIterator kB = kA + 1;
                kB != rkItems.end();
                ++kB)
            {
                // No coupling with itself.
                Q_ASSERT(*kA != *kB);
 
                // The address comparaison, ensure that a pair is always stored the same way.
                // Permutation are not possible.
                if(*kA < *kB)
                    kCouples.insert(QPair< const C*, const C* >(*kA, *kB));
                else
                    kCouples.insert(QPair< const C*, const C* >(*kB, *kA));
            }
        }
    }
 
    return kCouples;
}
PS : Lorsque je retire la ligne qui pose problème, ça compile normalement.
Agoudard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 13h46   #2
cob59
Membre chevronné
 
Inscription : décembre 2008
Messages : 490
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 490
Points : 751
Points : 751
Peut-être typename QSet< const C* >::ConstIterator ?
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 13h57   #3
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 179
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 179
Points : 2 492
Points : 2 492
C'est quasiment certainement ça, puisque C est un paramètre template, et qu'il est transmis à une autre template.
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 14h16   #4
Agoudard
Futur Membre du Club
 
Inscription : avril 2010
Messages : 96
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 96
Points : 17
Points : 17
Merci beaucoup,

C'était bien ça.
Je pense comprendre pourquoi il est nécéssaire de rajouter typename, mais une explication détaillée serait la bienvenue. (Ou peut être une voie sur laquelle chercher).

Merci.
Agoudard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 16h40   #5
leternel
Membre Expert
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 179
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 179
Points : 2 492
Points : 2 492
il faut un typename chaque fois que tu veux un type contenu dans un parametre template

Soit la fonction template <typename T> T::value_t incremente(T::base_t t){return t+1;}.

C'est joli, c'est logique, et ca suppose que T::value_t soit un type (pour lequel t+1 existe)

Nourrissons le.
Code :
1
2
3
4
5
6
7
8
9
10
11
template <typename T>
struct unconst{
    typedef T base_t;
    typedef T value_t;
}
 
template <typename T>
struct unconst<const T>{
    typedef const T base_t;
    typedef T value_t;
}
.

ceci est destiné à supprimer les const. (assez mal, c'est juste pour l'exemple)
On peut penser appeler int i =incremente< unconst<int> >(2);.

mais suppose qu'un petit malin écrive:
Code :
1
2
3
4
5
template <>
struct unconst<void>{
    int base_t;
    int value_t;
}
.

comment t'en sortirai tu avec la fonction incremente< unconst<void> >, maintenant que base_t et value_t ne sont meme plus des types?

typename sert à dire au compileur "Je pense que ceci est un type, tu es autorisé à le vérifier."

Ca, c'était ma petite explication. Pour plus de détails, il me semble que la faq contient une entrée sur le sujet.
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h48.


 
 
 
 
Partenaires

Hébergement Web