OVH Cloud OVH Cloud

g++ 3.4.2 et template

30 réponses
Avatar
docCarcass
Bonjour,
je rencontre un petit probl=E8me avec g++ 3.4.2.
Je dois compiler ce genre de code(qui n'est pas le mien) :

class Titi
{
protected :
int truc_;
public:
Titi():truc_(0){};
virtual ~Titi(){};
};

template<class T>
class Toto : public T
{
public:
void methode(void)
{
truc_++;
}
};

int main(int ac,char **av)
{
Toto<Titi> i;
i.methode();

return 0;
}

Cela compile avec g++ 3.3.4, icc 8.0 mais plus avec g++ 3.4.2 :

In file included from test.cc:1:
template.hh: In member function `void Toto<T>::methode()':
template.hh:16: erreur: =AB truc_ =BB non d=E9clar=E9 (premi=E8re utilisati=
on dans
cette fonction)
template.hh:16: erreur: (Chaque identificateur non d=E9clar=E9 est rapport=
=E9
seulement une seule fois pour la fonction dans laquelle il appara=EEt.)

Je comprend l'erreur mais s'agit-il d'un bug apparu recement dans g++ ou
alors d'un choix. S'il s'agit d'un choix existe-t-il une option pour
obtenir l'ancien comportement ?

Bien =E0 vous,
S=E9bastien

--

int main(){int j=3D1234,putchar();char t[]=3D":@abcdefghij-lmnopqrstuv"
"wxyz.\n",*i=3D"@jq:.pn.q:ibf.gd\noz.dn@ew\nlwh-i",*strchr();while(*i)
{j+=3Dstrchr(t,*i++)-t;j%=3Dsizeof t-1;putchar(t[j]);}return 0;}

10 réponses

1 2 3
Avatar
Gabriel Dos Reis
drkm writes:

| "Vincent Lascaux" writes:
|
| >> g++ 3.4.2 a raison. Il faut utiliser
|
| >> this->truc_++;
|
| > Pour quelle raison ? Est ce du à l'utilisation de template ?
|
| Oui, et à la recherche de nom en deux phases. Il faut rendre le nom
| dépendant du modèle.
|
| À confirmer, mes connaissances sur le sujet étant limitées.

Tu as raison.

-- Gaby
Avatar
Gabriel Dos Reis
drkm writes:

| "Christophe Lephay" writes:
|
| > Jean-Marc Bourguet wrote:
|
| >> drkm writes:
|
| >>> Jean-Marc Bourguet writes:
|
| >>>> Donc, pour que la recherche ait lieu aussi dans le contexte
| >>>> d'instanciation, il faut rendre le nom dépendant. Pour
| >>>> quelque chose qui devrait être un membre, le plus simple est
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| >>>> l'utilisation the this->.
|
| >>> Aurais-tu un exemple dans un autre cas ?
|
| >> La qualification par la classe de base (T::truc_), mais ça
| >> peut poser problème pour des membres virtuels.
|
| > Je crois que drkm parlait d'un autre exemple de problème, pas d'un autre
| > exemple de solution ;)
|
| Tout juste. Plus précisément, lorsque l'on veut rendre dépendant
| autre chose qu'un membre.

Si c'est un membre, c'est « this -> ».
Si c'est pas membre, alors ce sont les arguments.


f(t);

où t est de type T, par exemple.

-- Gaby
Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| À confirmer, mes connaissances sur le sujet étant limitées.

Tu as raison.


Sur la limite de mes connaissances ? Je sais ;-)

[ c'est bizarre, f.c.l.c++, depuis que tu ne réponds qu'en décallé
(décallé pour la plupart, pas pour Michel) ]

--drkm

Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:


<recherche de nom en deux phases et nom dépendant>

| Tout juste. Plus précisément, lorsque l'on veut rendre dépendant
| autre chose qu'un membre.

Si c'est un membre, c'est « this -> ».
Si c'est pas membre, alors ce sont les arguments.

f(t);

où t est de type T, par exemple.


Tu veux dire par exemple dans :

template< typename T >
struct A {
void g() {
T t ;
f( t ) ;
}
} ;

Dans ce cas, si j'ai bien compris, f n'est résolu qu'à
l'instanciation. Logique. Et il n'y a alors rien à faire pour rendre
le nom dépendant ; il l'est automatiquement, de par le type de son
argument.

Il n'y a que dans le cas d'un membre, alors, où l'on doit
explicitement rendre le nom dépendant, en le faisant précéder de
"this->".

Correct ?

--drkm

Avatar
drkm
"Michel Michaud" writes:

Dans le message ,

[ c'est bizarre, f.c.l.c++, depuis que tu ne réponds qu'en décallé
(décallé pour la plupart, pas pour Michel) ]


Moi, je me sens moi seul :-)
^^^


Lapsus révélateur ?-)

--drkm


Avatar
Fabien LE LEZ
On 24 Oct 2004 23:21:42 +0200, James Kanze :

Pourquoi ? C'est permis, même si ce n'est pas nécessaire.


On va dire que c'est juste une tentative d'obfuscation ;-)


--
;-)

Avatar
Gabriel Dos Reis
drkm writes:

| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| > | À confirmer, mes connaissances sur le sujet étant limitées.
|
| > Tu as raison.
|
| Sur la limite de mes connaissances ? Je sais ;-)

Je parlais de ton explication, pas les limites de ta connaissance.

| [ c'est bizarre, f.c.l.c++, depuis que tu ne réponds qu'en décallé
| (décallé pour la plupart, pas pour Michel) ]

Je ne comprends pas ce que tu voulais dire.

-- Gaby
Avatar
Gabriel Dos Reis
drkm writes:

| Gabriel Dos Reis writes:
|
| > drkm writes:
|
| <recherche de nom en deux phases et nom dépendant>
|
| > | Tout juste. Plus précisément, lorsque l'on veut rendre dépendant
| > | autre chose qu'un membre.
|
| > Si c'est un membre, c'est « this -> ».
| > Si c'est pas membre, alors ce sont les arguments.
|
| > f(t);
|
| > où t est de type T, par exemple.
|
| Tu veux dire par exemple dans :
|
| template< typename T >
| struct A {
| void g() {
| T t ;
| f( t ) ;
| }
| } ;
|
| Dans ce cas, si j'ai bien compris, f n'est résolu qu'à
| l'instanciation. Logique. Et il n'y a alors rien à faire pour rendre
| le nom dépendant ; il l'est automatiquement, de par le type de son
| argument.

Oui.

| Il n'y a que dans le cas d'un membre, alors, où l'on doit
| explicitement rendre le nom dépendant, en le faisant précéder de
| "this->".
|
| Correct ?

Oui.

Il y a une autre subtilité :

template< typename T >
struct A {
void g() {
T t ;
(f)(t) ; // ERREUR : f n'est pas dépendante
// et il n'y a pas de déclaration
// visible de "f"
}
};

En gros, en C++, un appel de fonction il faut vraiment l'écrire comme
tel :-)

-- Gaby
Avatar
kanze
Gabriel Dos Reis wrote in message
news:...

[...]
| Tout juste. Plus précisément, lorsque l'on veut rendre dépendant
| autre chose qu'un membre.

Si c'est un membre, c'est « this -> ».
Si c'est pas membre, alors ce sont les arguments.


Dans la logique, est-ce qu'il ne serait pas plutôt l'inverse. Ce sont
les paramètres qui rendent la fonction dépendante. Seulement, dans le
cas d'un membre, sans le this, le compilateur ne peut pas savoir qu'il y
a un paramètre implicit qui rendrait la fonction dépendante.

f(t);

où t est de type T, par exemple.


Par curiosité, est-ce qu'il y a un moyen de rendre dépendant une
fonction non membre qui n'a pas de paramètres ? Ou une donnée non
membre ? (Et ce n'est vraiment que de la curiosité, parce que je
n'arrive pas à imaginer un cas où ça serait nécessaire.)

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Gabriel Dos Reis
writes:

| drkm wrote in message
| news:...
| > Gabriel Dos Reis writes:
|
| > > drkm writes:
|
| > <recherche de nom en deux phases et nom dépendant>
|
| > > | Tout juste. Plus précisément, lorsque l'on veut rendre dépendant
| > > | autre chose qu'un membre.
|
| > > Si c'est un membre, c'est « this -> ».
| > > Si c'est pas membre, alors ce sont les arguments.
|
| > > f(t);
|
| > > où t est de type T, par exemple.
|
| > Tu veux dire par exemple dans :
|
| > template< typename T >
| > struct A {
| > void g() {
| > T t ;
| > f( t ) ;
| > }
| > } ;
|
| > Dans ce cas, si j'ai bien compris, f n'est résolu qu'à
| > l'instanciation. Logique. Et il n'y a alors rien à faire pour rendre
| > le nom dépendant ; il l'est automatiquement, de par le type de son
| > argument.
|
| Plus précisement : c'est le compilateur qui décide si un nom est
| dépendant ou non, et non le programmeur.

Ce qui n'est simplement pas vrai.


-- Gaby
1 2 3