Quelqu'un aurait-il l'amabilité de m'expliquer pourquoi le
code suivant serait invalide ? Messages d'erreur
incompréhensibles gracieusement fournis par gcc 4.0.0...
$ cat foo.cc
class MyClass {
};
template <typename T>
void
operator<<(MyClass& b, const T& t) {
}
enum { HSize };
int main() {
int i;
i<<HSize;
}
$
$ g++ foo.cc
foo.cc: In function 'int main()':
foo.cc:13: error: '<anonymous enum>' is/uses anonymous type
foo.cc:13: error: trying to instantiate 'template<class T> void
operator<<(MyClass&, const T&)'
$
Quelqu'un aurait-il l'amabilité de m'expliquer pourquoi le
code suivant serait invalide ? Messages d'erreur
incompréhensibles gracieusement fournis par gcc 4.0.0...
$ cat foo.cc
class MyClass {
};
template <typename T>
void
operator<<(MyClass& b, const T& t) {
}
enum { HSize };
int main() {
int i;
i<<HSize;
}
$
$ g++ foo.cc
foo.cc: In function 'int main()':
foo.cc:13: error: '<anonymous enum>' is/uses anonymous type
foo.cc:13: error: trying to instantiate 'template<class T> void
operator<<(MyClass&, const T&)'
$
Quelqu'un aurait-il l'amabilité de m'expliquer pourquoi le
code suivant serait invalide ? Messages d'erreur
incompréhensibles gracieusement fournis par gcc 4.0.0...
$ cat foo.cc
class MyClass {
};
template <typename T>
void
operator<<(MyClass& b, const T& t) {
}
enum { HSize };
int main() {
int i;
i<<HSize;
}
$
$ g++ foo.cc
foo.cc: In function 'int main()':
foo.cc:13: error: '<anonymous enum>' is/uses anonymous type
foo.cc:13: error: trying to instantiate 'template<class T> void
operator<<(MyClass&, const T&)'
$
surpris en ce qui concerne les templates. Dans la mésure où la
Bonjour Monsieur,
surpris en ce qui concerne les templates. Dans la mésure où la
Bonjour Monsieur,
surpris en ce qui concerne les templates. Dans la mésure où la
Bonjour Monsieur,
wrote:surpris en ce qui concerne les templates. Dans la mésure où la
Je me permet une petite remarque :
"Dans la mesure" au lieu de "Dans la mésure".
Comme personne n'ose/ne juge nécessaire de vous reprendre, et
que vous la faite souvent (ça n'a pas l'air d'être un oubli),
et que vu votre niveau de français, vous avez largement la
capacité de l'intégrer, je me suis permis cette petite
remarque, en toute humilité.
kanze@gabi-soft.fr wrote:
surpris en ce qui concerne les templates. Dans la mésure où la
Je me permet une petite remarque :
"Dans la mesure" au lieu de "Dans la mésure".
Comme personne n'ose/ne juge nécessaire de vous reprendre, et
que vous la faite souvent (ça n'a pas l'air d'être un oubli),
et que vu votre niveau de français, vous avez largement la
capacité de l'intégrer, je me suis permis cette petite
remarque, en toute humilité.
wrote:surpris en ce qui concerne les templates. Dans la mésure où la
Je me permet une petite remarque :
"Dans la mesure" au lieu de "Dans la mésure".
Comme personne n'ose/ne juge nécessaire de vous reprendre, et
que vous la faite souvent (ça n'a pas l'air d'être un oubli),
et que vu votre niveau de français, vous avez largement la
capacité de l'intégrer, je me suis permis cette petite
remarque, en toute humilité.
Le message ne me semble pas si mauvais que ça. Il dit exactement
ce que tu fais de faux : tu utilise un type anonyme en essayant
d'initialiser un template. Alors que c'est dit très
explicitement dans la norme que des types sans nom ne peuvent
pas servir ici. (J'avoue que pour une fois, la norme ne m'a pas
surpris en ce qui concerne les templates. Dans la mésure où la
norme exige en général que le type d'instantiation soit
globalement visible, je vois mal comment il permettrait des
instantiations sur des types anonyme.)
Le message ne me semble pas si mauvais que ça. Il dit exactement
ce que tu fais de faux : tu utilise un type anonyme en essayant
d'initialiser un template. Alors que c'est dit très
explicitement dans la norme que des types sans nom ne peuvent
pas servir ici. (J'avoue que pour une fois, la norme ne m'a pas
surpris en ce qui concerne les templates. Dans la mésure où la
norme exige en général que le type d'instantiation soit
globalement visible, je vois mal comment il permettrait des
instantiations sur des types anonyme.)
Le message ne me semble pas si mauvais que ça. Il dit exactement
ce que tu fais de faux : tu utilise un type anonyme en essayant
d'initialiser un template. Alors que c'est dit très
explicitement dans la norme que des types sans nom ne peuvent
pas servir ici. (J'avoue que pour une fois, la norme ne m'a pas
surpris en ce qui concerne les templates. Dans la mésure où la
norme exige en général que le type d'instantiation soit
globalement visible, je vois mal comment il permettrait des
instantiations sur des types anonyme.)
writes:
[...]
| Alors que c'est dit très
| explicitement dans la norme que des types sans nom ne peuvent
| pas servir ici.
Ah bon. Alors même qu'il y a un Core Issue en discussion pour ça.
| (J'avoue que pour une fois, la norme ne m'a pas surpris en
| ce qui concerne les templates. Dans la mésure où la norme
| exige en général que le type d'instantiation soit
| globalement visible, je vois mal comment il permettrait des
| instantiations sur des types anonyme.)
Il n'y a aucun rapport.
(1) le type en question n'est pas utilisé pour faire des
opérations
sur les templates;
(2) et même si l'énumération en question était utilisée pour
faire
des opérations sur les templates, la notion de visibilité
concerne les *noms* et pas les types.
kanze@gabi-soft.fr writes:
[...]
| Alors que c'est dit très
| explicitement dans la norme que des types sans nom ne peuvent
| pas servir ici.
Ah bon. Alors même qu'il y a un Core Issue en discussion pour ça.
| (J'avoue que pour une fois, la norme ne m'a pas surpris en
| ce qui concerne les templates. Dans la mésure où la norme
| exige en général que le type d'instantiation soit
| globalement visible, je vois mal comment il permettrait des
| instantiations sur des types anonyme.)
Il n'y a aucun rapport.
(1) le type en question n'est pas utilisé pour faire des
opérations
sur les templates;
(2) et même si l'énumération en question était utilisée pour
faire
des opérations sur les templates, la notion de visibilité
concerne les *noms* et pas les types.
writes:
[...]
| Alors que c'est dit très
| explicitement dans la norme que des types sans nom ne peuvent
| pas servir ici.
Ah bon. Alors même qu'il y a un Core Issue en discussion pour ça.
| (J'avoue que pour une fois, la norme ne m'a pas surpris en
| ce qui concerne les templates. Dans la mésure où la norme
| exige en général que le type d'instantiation soit
| globalement visible, je vois mal comment il permettrait des
| instantiations sur des types anonyme.)
Il n'y a aucun rapport.
(1) le type en question n'est pas utilisé pour faire des
opérations
sur les templates;
(2) et même si l'énumération en question était utilisée pour
faire
des opérations sur les templates, la notion de visibilité
concerne les *noms* et pas les types.
writes:
[...]
| > (2) et même si l'énumération en question était utilisée
| > pour faire des opérations sur les templates, la
| > notion de visibilité concerne les *noms* et pas les
| > types.
| En ce qui concerne (2), j'aurais cru que §14.3.1 (« A local
| type, at type with no linkage, an UNNAMED TYPE or a type
| compounded from any of these types shal not be used as a
| template-argument for a template type-parameter. ») rendait le
| code illégal. Mais comme j'ai dit, les règles en ce qui concerne
| les templates sont trop compliquées pour que j'arrive réelement
| à les comprendre.
Le passage que tu cites est vrai, mais au fond ce passage ne
resiste pas vraiment à l'analyse et je l'ai déjà dit dans EWG
à Redmond lorsque quelqu'un a proposé à Oxford (Avril 2003)
d'autoriser les types locaux en tant qu'arguments de template
(tous les implémenteurs à l'époque ont dit « oui », c'est
faisable) et qu'à Redmond j'ai entendu une « réticence » pour
des raisons que j'ai oubliées.
J'ai entendu des rumeurs sur le mangling, mais comme je l'ai
dejà fait observé, ce n'est pas parce que quelque chose est
local ou n'a pas de nom qu'on ne peut ps le mangler. Pour le
premier cas il suffit de considérer les variables locales
statiques et se rendre compte que tous les compilateurs
corrects les manglent (en ce qui concerne l'idiome courant
d'initialization). Pour le second cas, il suffit de considérer
les « unnamed namespace » et ce qu'ils contiennent.
| Mon interprétation, ici, c'est que même si c'est le
| compilateur qui a déduit le type, c'est le type qui est
| l'argument. Et que le type en question n'a pas de nom. (Mais
| en pensant -- je dirais aussi qu'un type comme int* n'a pas
| de nom. Or que je suis assez sûr qu'on ne veut pas interdire
| ça comme paramètre d'un template. Alors, je n'y comprends
| rien.)
Comme j'ai dit, quelque part quelqu'un a confondu « type » et
« nom » et a créé cette confusion. :-( Au debut « linkage »
concernait les noms, puis il a été étendu aux types de
fonctions (contrairement à l'avertissement de l'ARM) ; et
maintenant il est impliciement utilisé pour autres choses.
Le problème avec le code est que pour faire la résolution de
surcharge de « << », le compilateur doit considérer les «
operator<< » dans la portée ainsi que ceux qui sont câblés. En
particulier, pour celui qui est template, le compilateur doit
déduire les arguments de templates. Or cette phase
(préliminaire) déduit un type non nommé, alors le compilateur
se plaint -- même et surtout si la fonction correspondante
n'est jamais utilisée. Intéressant, n'est-ce pas ?
On pourrait faire une règle disant que c'est invalide
uniquement si la fonction est choisie, mais je soupçonne que
cela créerait toujours de la confusion. Je pense que la
solution est de simplement autoriser ces choses là. La
restriction est artificielle.
Ah, en ce qui concerne le core issue en question il n'y a pas
encore de numéro public mais c'est devant le CWG (i.e.
reflecteur). Note aussi l'explication
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#278
de Mike Miller tendrait à supporter la vision qu'on peut
mangler une énumération, même si elle n'a pas de nom :-)
kanze@gabi-soft.fr writes:
[...]
| > (2) et même si l'énumération en question était utilisée
| > pour faire des opérations sur les templates, la
| > notion de visibilité concerne les *noms* et pas les
| > types.
| En ce qui concerne (2), j'aurais cru que §14.3.1 (« A local
| type, at type with no linkage, an UNNAMED TYPE or a type
| compounded from any of these types shal not be used as a
| template-argument for a template type-parameter. ») rendait le
| code illégal. Mais comme j'ai dit, les règles en ce qui concerne
| les templates sont trop compliquées pour que j'arrive réelement
| à les comprendre.
Le passage que tu cites est vrai, mais au fond ce passage ne
resiste pas vraiment à l'analyse et je l'ai déjà dit dans EWG
à Redmond lorsque quelqu'un a proposé à Oxford (Avril 2003)
d'autoriser les types locaux en tant qu'arguments de template
(tous les implémenteurs à l'époque ont dit « oui », c'est
faisable) et qu'à Redmond j'ai entendu une « réticence » pour
des raisons que j'ai oubliées.
J'ai entendu des rumeurs sur le mangling, mais comme je l'ai
dejà fait observé, ce n'est pas parce que quelque chose est
local ou n'a pas de nom qu'on ne peut ps le mangler. Pour le
premier cas il suffit de considérer les variables locales
statiques et se rendre compte que tous les compilateurs
corrects les manglent (en ce qui concerne l'idiome courant
d'initialization). Pour le second cas, il suffit de considérer
les « unnamed namespace » et ce qu'ils contiennent.
| Mon interprétation, ici, c'est que même si c'est le
| compilateur qui a déduit le type, c'est le type qui est
| l'argument. Et que le type en question n'a pas de nom. (Mais
| en pensant -- je dirais aussi qu'un type comme int* n'a pas
| de nom. Or que je suis assez sûr qu'on ne veut pas interdire
| ça comme paramètre d'un template. Alors, je n'y comprends
| rien.)
Comme j'ai dit, quelque part quelqu'un a confondu « type » et
« nom » et a créé cette confusion. :-( Au debut « linkage »
concernait les noms, puis il a été étendu aux types de
fonctions (contrairement à l'avertissement de l'ARM) ; et
maintenant il est impliciement utilisé pour autres choses.
Le problème avec le code est que pour faire la résolution de
surcharge de « << », le compilateur doit considérer les «
operator<< » dans la portée ainsi que ceux qui sont câblés. En
particulier, pour celui qui est template, le compilateur doit
déduire les arguments de templates. Or cette phase
(préliminaire) déduit un type non nommé, alors le compilateur
se plaint -- même et surtout si la fonction correspondante
n'est jamais utilisée. Intéressant, n'est-ce pas ?
On pourrait faire une règle disant que c'est invalide
uniquement si la fonction est choisie, mais je soupçonne que
cela créerait toujours de la confusion. Je pense que la
solution est de simplement autoriser ces choses là. La
restriction est artificielle.
Ah, en ce qui concerne le core issue en question il n'y a pas
encore de numéro public mais c'est devant le CWG (i.e.
reflecteur). Note aussi l'explication
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#278
de Mike Miller tendrait à supporter la vision qu'on peut
mangler une énumération, même si elle n'a pas de nom :-)
writes:
[...]
| > (2) et même si l'énumération en question était utilisée
| > pour faire des opérations sur les templates, la
| > notion de visibilité concerne les *noms* et pas les
| > types.
| En ce qui concerne (2), j'aurais cru que §14.3.1 (« A local
| type, at type with no linkage, an UNNAMED TYPE or a type
| compounded from any of these types shal not be used as a
| template-argument for a template type-parameter. ») rendait le
| code illégal. Mais comme j'ai dit, les règles en ce qui concerne
| les templates sont trop compliquées pour que j'arrive réelement
| à les comprendre.
Le passage que tu cites est vrai, mais au fond ce passage ne
resiste pas vraiment à l'analyse et je l'ai déjà dit dans EWG
à Redmond lorsque quelqu'un a proposé à Oxford (Avril 2003)
d'autoriser les types locaux en tant qu'arguments de template
(tous les implémenteurs à l'époque ont dit « oui », c'est
faisable) et qu'à Redmond j'ai entendu une « réticence » pour
des raisons que j'ai oubliées.
J'ai entendu des rumeurs sur le mangling, mais comme je l'ai
dejà fait observé, ce n'est pas parce que quelque chose est
local ou n'a pas de nom qu'on ne peut ps le mangler. Pour le
premier cas il suffit de considérer les variables locales
statiques et se rendre compte que tous les compilateurs
corrects les manglent (en ce qui concerne l'idiome courant
d'initialization). Pour le second cas, il suffit de considérer
les « unnamed namespace » et ce qu'ils contiennent.
| Mon interprétation, ici, c'est que même si c'est le
| compilateur qui a déduit le type, c'est le type qui est
| l'argument. Et que le type en question n'a pas de nom. (Mais
| en pensant -- je dirais aussi qu'un type comme int* n'a pas
| de nom. Or que je suis assez sûr qu'on ne veut pas interdire
| ça comme paramètre d'un template. Alors, je n'y comprends
| rien.)
Comme j'ai dit, quelque part quelqu'un a confondu « type » et
« nom » et a créé cette confusion. :-( Au debut « linkage »
concernait les noms, puis il a été étendu aux types de
fonctions (contrairement à l'avertissement de l'ARM) ; et
maintenant il est impliciement utilisé pour autres choses.
Le problème avec le code est que pour faire la résolution de
surcharge de « << », le compilateur doit considérer les «
operator<< » dans la portée ainsi que ceux qui sont câblés. En
particulier, pour celui qui est template, le compilateur doit
déduire les arguments de templates. Or cette phase
(préliminaire) déduit un type non nommé, alors le compilateur
se plaint -- même et surtout si la fonction correspondante
n'est jamais utilisée. Intéressant, n'est-ce pas ?
On pourrait faire une règle disant que c'est invalide
uniquement si la fonction est choisie, mais je soupçonne que
cela créerait toujours de la confusion. Je pense que la
solution est de simplement autoriser ces choses là. La
restriction est artificielle.
Ah, en ce qui concerne le core issue en question il n'y a pas
encore de numéro public mais c'est devant le CWG (i.e.
reflecteur). Note aussi l'explication
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#278
de Mike Miller tendrait à supporter la vision qu'on peut
mangler une énumération, même si elle n'a pas de nom :-)