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
writes:

| 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

???

quelle « la » logique ?

peut-tu rendre explicites tes hypothèses implicites ?

| 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.)

Je n'ai compris la prose ; peux-tu reformuler en symboles ?

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

| 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

???

quelle « la » logique ?


C-à-d que toi aussi, tu as des problèmes à voir une logique dans tout
ça.

peut-tu rendre explicites tes hypothèses implicites ?


C'est que selon la norme, une expression du type postfix-expression
« ( expression-list[opt] ) n'est dépendant que si une des expressions
dans l'expression-list dépend d'un paramètre de type. Ce sont en premier
lieu les paramètres qui rendent le nom dépendant. S'ils ne le font pas,
il faut alors qu'on fasse quelque chose pour que le postfix-expression
lui même soit dépendant.

| 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.)

Je n'ai compris la prose ; peux-tu reformuler en symboles ?


Mettons que j'ai une expression, « f() ». En supposant que le symbole f
n'est pas local au template, il serait recherché comme n'étant pas
dépendant. Or, supposons que pour une raison quelconque, je veux qu'il
soit dépendant, que la recherche ne se fait au moment de
l'instantiation. Est-ce possible ?

Note bien que ça pourrait être potentiellement intéressant dans le cas
où la fonction prenne un paramètre, disons « f(0) ». Dans le cas, par
exemple, que le programmeur veut exiger qu'un des types d'instantiation
ait un constructeur qui prenne un int, et qu'il existe une fonction f
qui prend ce type. Ou quelque chose du genre ; j'avoue que je comprends
assez mal tout ces complications, mais j'essaie de comprendre.

--
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
drkm
writes:

Je n'ai pas le temps, et sans doute les compétences, pour chercher
ce point dans la norme, et je n'ai pas encore le livre de Josuttis et
Vandervoorde. Je me base ici sur le bon sens. Mais j'aimerais savoir
si cela est correct (et connaître le verset serait encore mieux).

Dans un template de classe, l'utilisation de this-> rend le nom
dépendant si (et seulement si) la classe elle-même dépend en quelque
sort d'un paramètre de template ; par exemple, si la classe en dérive.


Je suppose que dériver d'une instanciation d'une classe sur un
paramètre de template (et non du paramètre lui-même) est également
dépendant.

J'ai finalement jeté un coup d'oeil à la norme, et il me semble que
c'est bien ce que disent :

14.6.2.2/2 :

_this_ is type-dependant if the class type of the enclosing
member function is dependant

14.6.2.1/1

A type is dependant if it is

- a template parameter,

[...]

- a compound type constructed from any dependant type,

[...]

- a /template-id/ in which either the template name is a
template parameter or any of the template arguments is a
dependant type or an expression that is type-dependant or
value-dependant.

Correct ?

--drkm

Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| [ 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.


Une certaine partie du ton de f.c.l.c++ vient de tes contributions.
Qui avaient un taux de réactivité plutôt élevé, ce qui donnait parfois
lieu à des échanges passionnés (parfois passionnants) et rapides.

Aujourd'hui, tu réponds plus « par lots » à ce qui a été dit dans la
précédente moitié du jour, qui correspond à un horaire normal dans le
fuseau horaire de la France, où se trouvent plus ou moins la plupart
des contributeurs (du moins actifs, en tenant compte de leur horaire
de participation).

Bref, tes réponses ont moins de réactivité, c'est dommage ;-(

--drkm

Avatar
Gabriel Dos Reis
writes:

[...]

| > | 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.)
|
| > Je n'ai compris la prose ; peux-tu reformuler en symboles ?
|
| Mettons que j'ai une expression, « f() ». En supposant que le symbole f
| n'est pas local au template, il serait recherché comme n'étant pas
| dépendant.

Exact.

| Or, supposons que pour une raison quelconque, je veux qu'il
| soit dépendant, que la recherche ne se fait au moment de
| l'instantiation. Est-ce possible ?

En isolation, non, ce n'est pas possible. Il faut absolument injecter
une information disant de quoi ce symbole pourrait dépendre. C'est
toute l'essence de 14.6.3.

Ce que certains font, c'est d'écire « T::f() », où f serait par
exemple un membre statique de T ou de classes de base de T.
Une version un peu évoluée de cela est l'utilisation de traits -- mais
encore une fois « f() » n'apparaît plus isolé.

-- Gaby
Avatar
Jean-Marc Bourguet
writes:

Mettons que j'ai une expression, « f() ». En supposant que le
symbole f n'est pas local au template, il serait recherché comme
n'étant pas dépendant. Or, supposons que pour une raison quelconque,
je veux qu'il soit dépendant, que la recherche ne se fait au moment
de l'instantiation. Est-ce possible ?


Si ce n'est pas un membre et qu'il n'a pas de parametre d'un type
argument template, tu en fais un argument template.

La recherche de noms dans le contexte d'instanciation pour les
non-membres est simplement un moyen d'eviter d'avoir a passer des
arguments template. Si ce qui est fourni ne te convient pas -- que ce
ne soit pas un nom dependant ou que la recherche par nom ne soit pas
assez souple --, tu passes a la version lourde et tu specifies
explicitement les arguments.

Note que de ce point de vue, on peut considerer les traits comme un
moyen de regrouper une serie d'arguments templates -- comme passer une
struct peut etre considere comme un moyen de regrouper une serie
d'arguments donnee.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Note que de ce point de vue, on peut considerer les traits comme un
| moyen de regrouper une serie d'arguments templates -- comme passer une
| struct peut etre considere comme un moyen de regrouper une serie
| d'arguments donnee.

C'est exactement cela.
C'est aussi l'une des raisons pour lesquelles je voudrais pouvoir
utiliser les namespaces comme arguments de template, car les namespaces
sont plus flexibles sur certains points.

Malheureusement, je n'ai jamais eu le temps d'écrire une proposition
formelle. Alors j'en parle de temps en temps en espérant que quelqu'un
saisira la balle au vol -- pour ceux qui sont intéressés la suggestion
est déjà sur la liste de EWG, mais il n'y a pas de proposition
correspondante.

-- Gaby
Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
writes:

Mettons que j'ai une expression, « f() ». En supposant que le
symbole f n'est pas local au template, il serait recherché comme
n'étant pas dépendant. Or, supposons que pour une raison quelconque,
je veux qu'il soit dépendant, que la recherche ne se fait au moment
de l'instantiation. Est-ce possible ?


Si ce n'est pas un membre et qu'il n'a pas de parametre d'un type
argument template, tu en fais un argument template.

La recherche de noms dans le contexte d'instanciation pour les
non-membres est simplement un moyen d'eviter d'avoir a passer des
arguments template. Si ce qui est fourni ne te convient pas -- que ce
ne soit pas un nom dependant ou que la recherche par nom ne soit pas
assez souple --, tu passes a la version lourde et tu specifies
explicitement les arguments.


Bien vu, le rapprochement aux paramètres de template. C'est la première
fois que j'entends les symboles dépendants présentés de cette façon, et
je trouve que ça rend l'affaire un petit peu plus clair.

En fait, le genre de chose à laquelle je pensais, c'était quelque chose
du genre :

template< typename T >
struct S
{
void f() { T t = initialValue() ; /* ... */ }
} ;

où l'intention était que l'utilisateur fournisse une fonction
initialValue() qui renvoyait la bonne valeur. Mais déjà, je
reconnaissais qu'il existe de meilleurs solutions -- aujourd'hui, en
tout cas, je me servirai prèsque sûrement d'un paramètre de trait, par
exemple. Mais j'étais quand même curieux, parce que ça semble une
lacune, au moins du point de vue de l'orthogonalité : certaines
fonctions peuvent être dépendente ou non, selon, tandis que d'autres ne
peuvent jamais être dépendente.

Note que de ce point de vue, on peut considerer les traits comme un
moyen de regrouper une serie d'arguments templates -- comme passer une
struct peut etre considere comme un moyen de regrouper une serie
d'arguments donnee.


Tout à fait. En revanche, je n'aimerais pas à avoir à spécifier
basic_string avec tous ses paramètres s'il n'y avait pas un paramètre
trait:-).

--
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:

| Jean-Marc Bourguet wrote in message
| news:...
| > writes:
|
| > > Mettons que j'ai une expression, « f() ». En supposant que le
| > > symbole f n'est pas local au template, il serait recherché comme
| > > n'étant pas dépendant. Or, supposons que pour une raison quelconque,
| > > je veux qu'il soit dépendant, que la recherche ne se fait au moment
| > > de l'instantiation. Est-ce possible ?
|
| > Si ce n'est pas un membre et qu'il n'a pas de parametre d'un type
| > argument template, tu en fais un argument template.
|
| > La recherche de noms dans le contexte d'instanciation pour les
| > non-membres est simplement un moyen d'eviter d'avoir a passer des
| > arguments template. Si ce qui est fourni ne te convient pas -- que ce
| > ne soit pas un nom dependant ou que la recherche par nom ne soit pas
| > assez souple --, tu passes a la version lourde et tu specifies
| > explicitement les arguments.
|
| Bien vu, le rapprochement aux paramètres de template. C'est la première
| fois que j'entends les symboles dépendants présentés de cette façon, et
| je trouve que ça rend l'affaire un petit peu plus clair.

donc tu n'as pas dû avoir lu TC++PL3 :-)

[...]

| > Note que de ce point de vue, on peut considerer les traits comme un
| > moyen de regrouper une serie d'arguments templates -- comme passer une
| > struct peut etre considere comme un moyen de regrouper une serie
| > d'arguments donnee.
|
| Tout à fait. En revanche, je n'aimerais pas à avoir à spécifier
| basic_string avec tous ses paramètres s'il n'y avait pas un paramètre
| trait:-).

En réalité, nous sommes un certain nombre (y compris Matt Austern) à
voir enlever char_traits<>, si c'était possible. Il ne sert qu'à
alourdir les choses. Il n'a jamais servi de manière utile.

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

[...]
| Tout à fait. En revanche, je n'aimerais pas à avoir à spécifier
| basic_string avec tous ses paramètres s'il n'y avait pas un
| paramètre trait:-).

En réalité, nous sommes un certain nombre (y compris Matt Austern) à
voir enlever char_traits<>, si c'était possible. Il ne sert qu'à
alourdir les choses. Il n'a jamais servi de manière utile.


N'est-ce pas ? (En ce qui concerne Matt, je sais qu'il n'a jamais été
content de std::basic_string. Comme beaucoup d'autres, d'ailleurs.)

À l'occasion, je crois qu'une certaine reflection sur ce qu'on veut
faire pour supporter des caractères et du texte ne serait pas inutile.
(À l'époque de la normalisation, ça aurait été un peu prémature, AMHA.
Mais nos connaissances dans le domaine ont évoluées, et je crois que le
moment est juste.)

--
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

1 2 3