OVH Cloud OVH Cloud

template et fonction

5 réponses
Avatar
aVrama
Bonjour à tous,
J'effectue un portage d'une application C++ utilisant une nouvelle
version du compilo gcc. Je me heurte à pas mal de problème concernant
les templates (que je trouve assez compliqué à mettre en place):

Dans mon fichier stm.h, j'ai le code suivant:

...
template< class T, class S, class M >
template< typename S::Id SI, typename M::Id MI>
inline void StateMachine<T,1,S,M>::initTrans()
{
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::doTrans<SI, MI>; // ligne 232
}
...

Le gcc me donne le message suivant:
../stm.h: In member function `void Tools::Design::StateMachine<T, 1, S,
M>::initTransition()':
../stm.h(232): error: expected primary-expression before ';' token

Je ne sais pas comment modifier mon code pour que cela passe. J'ai
essayé pas mal de syntaxe en cherchant sur le net sans succès. Je pense
qu'il manque un 'typename' autour des SI et MI...

Merci pour votre aide.
aVr

5 réponses

Avatar
Pierre Barbier de Reuille
aVrama wrote:
Bonjour à tous,
J'effectue un portage d'une application C++ utilisant une nouvelle
version du compilo gcc. Je me heurte à pas mal de problème concernant
les templates (que je trouve assez compliqué à mettre en place):

Dans mon fichier stm.h, j'ai le code suivant:

...
template< class T, class S, class M >
template< typename S::Id SI, typename M::Id MI>
inline void StateMachine<T,1,S,M>::initTrans()
{
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::doTrans<SI, MI>; // ligne 232
}
...

Le gcc me donne le message suivant:
../stm.h: In member function `void Tools::Design::StateMachine<T, 1, S,
M>::initTransition()':
../stm.h(232): error: expected primary-expression before ';' token

Je ne sais pas comment modifier mon code pour que cela passe. J'ai
essayé pas mal de syntaxe en cherchant sur le net sans succès. Je pen se
qu'il manque un 'typename' autour des SI et MI...


Mouai ... pour pouvoir repondre, il faudrait un exemple minimum qui
soit compilable ...

Pierre


Merci pour votre aide.
aVr


Avatar
Jean-Marc Bourguet
aVrama writes:

Bonjour à tous,
J'effectue un portage d'une application C++ utilisant une nouvelle version
du compilo gcc. Je me heurte à pas mal de problème concernant les templates
(que je trouve assez compliqué à mettre en place):

Dans mon fichier stm.h, j'ai le code suivant:

...
template< class T, class S, class M >
template< typename S::Id SI, typename M::Id MI>
inline void StateMachine<T,1,S,M>::initTrans()
{
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::doTrans<SI, MI>; // ligne 232
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::template doTrans<SI, MI>; // ligne 232


}
...

Le gcc me donne le message suivant:
../stm.h: In member function `void Tools::Design::StateMachine<T, 1, S,
M>::initTransition()':
../stm.h(232): error: expected primary-expression before ';' token

Je ne sais pas comment modifier mon code pour que cela passe. J'ai essayé
pas mal de syntaxe en cherchant sur le net sans succès. Je pense qu'il
manque un 'typename' autour des SI et MI...


template resouds pour les templates le meme probleme que typename pour les
types. Mais comme SI et MI sont des valeurs et que donc il n'y a pas a les
qualifier avec typename, tu devrais peut-etre regarder a nouveau pourquoi
c'est necessaire.

A+

--
Jean-Marc

Avatar
aVrama
aVrama writes:

Bonjour à tous,
J'effectue un portage d'une application C++ utilisant une nouvelle version
du compilo gcc. Je me heurte à pas mal de problème concernant les templates
(que je trouve assez compliqué à mettre en place):

Dans mon fichier stm.h, j'ai le code suivant:

...
template< class T, class S, class M >
template< typename S::Id SI, typename M::Id MI>
inline void StateMachine<T,1,S,M>::initTrans()
{
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::doTrans<SI, MI>; // ligne 232
m_Matrix[SI][MI] = &StateMachine<T,1,S,M>::template doTrans<SI, MI>; // ligne 232


}
...

Le gcc me donne le message suivant:
../stm.h: In member function `void Tools::Design::StateMachine<T, 1, S,
M>::initTransition()':
../stm.h(232): error: expected primary-expression before ';' token

Je ne sais pas comment modifier mon code pour que cela passe. J'ai essayé
pas mal de syntaxe en cherchant sur le net sans succès. Je pense qu'il
manque un 'typename' autour des SI et MI...


template resouds pour les templates le meme probleme que typename pour les
types. Mais comme SI et MI sont des valeurs et que donc il n'y a pas a les
qualifier avec typename, tu devrais peut-etre regarder a nouveau pourquoi
c'est necessaire.

A+

Merci, c'est tout a fait cela.

C'est vrai que je ne comprends pas pourquoi il faut mettre parfois
typename devant les attributs ou variables et template devant les
méthodes et, parfois non. Cela semble dépendre des versions des compilos...
Encore merci pour votre aide,
aVr


Avatar
James Kanze
aVrama wrote:

C'est vrai que je ne comprends pas pourquoi il faut mettre parfois
typename devant les attributs ou variables et template devant les
méthodes et, parfois non. Cela semble dépendre des versions des compi los...


Ça dépend effectivement des versions des compilateurs.
Historiquement, la plupart des compilateurs ont implémenté des
templates un peu comme des macros peaufinés, en ne régardant
dedans que lors de l'instantiation. La norme a voulu en revanche
que 1) le compilateur soit capable de detecter des erreurs de
syntaxe lors de la définition du template, sans la moindre
instantiation, et 2) que l'auteur du template sache d'où
viennent les noms qu'il utilise. Seulement, certains noms dans
un template dépend bien des paramètres d'instantiation -- et la
grammaire du C++ change selon qu'un nom désigne un type, un
template ou d'autre chose. Du coup, si le nom dépend des
paramètres du template, il faut signaler au compilateur ce qu'il
est. (Le défaut, c'est qu'il désigne ni un type, ni un
template.) Peu à peu, les compilateurs s'adoptent aux nouvelles
règles, ce qui fait que ce qui fonctionnait avec d'anciennes
versions ne fonctionnent souvent pas avec de nouvelles.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Jean-Marc Bourguet
aVrama writes:

C'est vrai que je ne comprends pas pourquoi il faut mettre parfois
typename devant les attributs ou variables et template devant les
méthodes et, parfois non.


L'objectif de la regle est de permettre une verification syntaxique de la
definition des templates hors de toute instanciation. Pour ce faire, il
faut savoir ce qu'un nom utilise comme membre d'un parametre template (on
parle alors de nom dependant) designe. Les regles du C++ sont telles qu'il
n'y a que trois cas a considerer:
- il designe un type, il faut alors le qualifier avec 'typename'
- il designe un template, il faut alors le qualifier avec 'template'
- il designe autre chose, on peut l'utiliser sans le qualifier.

A savoir, pour qu'un nom soit dependant, il faut qu'il soit visiblement
utilise comme membre. Le cas problematique est quand la classe herite d'un
de ses parametres templates, il faut alors qualifier le nom (avec this-> ou
avec le parametre template suivant les cas) pour qu'il soit considere comme
dependant.

Cela semble dépendre des versions des compilos...


Tous les compilos ne sont pas encore a jour... bien que la norme ait ete
publiee il y a 8 ans et que ces changements aient ete connus avant.

A+

--
Jean-Marc