Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Adresse d'une fonction template

12 réponses
Avatar
Thierry Noc
J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
template (gcc 3.4.2):


extern void libfn(int(*)(int));


template <typename T>
class maclass {

friend int fn(int)
{
T var;
return(0);
}

void setup()
{
// libfn(fn); // OK avec gcc 2.95
// libfn(fn); // `fn' undeclared (first use this
function)
// libfn(fn<T>); // `fn' undeclared (first use this
function)
libfn(::fn<T>); // `::fn' has not been declared
}

};

Une idée ?

10 réponses

1 2
Avatar
Jean-Sebastien Mouret
Thierry Noc writes:

J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
template (gcc 3.4.2):


extern void libfn(int(*)(int));


template <typename T>
class maclass {

friend int fn(int)
{
T var;
return(0);
}

void setup()
{
// libfn(fn); // OK avec gcc 2.95
// libfn(fn); // `fn' undeclared (first use this
function)
// libfn(fn<T>); // `fn' undeclared (first use this
function)
libfn(::fn<T>); // `::fn' has not been declared
}

};

Une idée ?



libfn(maclasse<T>::fn);


--
js

Avatar
Jean-Sebastien Mouret
Jean-Sebastien Mouret writes:

Thierry Noc writes:

J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
template (gcc 3.4.2):


extern void libfn(int(*)(int));


template <typename T>
class maclass {

friend int fn(int)
{
T var;
return(0);
}

void setup()
{
// libfn(fn); // OK avec gcc 2.95
// libfn(fn); // `fn' undeclared (first use this
function)
// libfn(fn<T>); // `fn' undeclared (first use this
function)
libfn(::fn<T>); // `::fn' has not been declared
}

};

Une idée ?



libfn(maclasse<T>::fn);


désolé, ca marche pas, je retire ce que j'ai dit.


--
js


Avatar
xavier
Thierry Noc a dit le 25/01/2005 11:40:
friend int fn(int)
{
T var;
return(0);
}


Je ne suis pas sur que la définition d'une fonction à l'intérieur d'une
déclaration "friend" soit valide.

Une idée ?


Ceci fonctionne :

extern void libfn(int(*)(int));

template <typename T> int fn(int);

template <typename T>
class maclass {

friend int fn<T>(int);

void setup() {
libfn(&fn<T>);
}

};

template <typename T>
int fn(int) {
T a;
return 0;
}

xavier

Avatar
Thierry Noc
xavier wrote:


Je ne suis pas sur que la définition d'une fonction à l'intérieur d'une
déclaration "friend" soit valide.

Une idée ?


Ceci fonctionne :



En effet, merci du tuyeau.
En fait gcc 2.95 était trop intelligent, avec la 3, il faut lui macher le
boulot et encore il prend 4 fois plus de temps pour compiler... bah je
crois que je vais finir par trouver les bons cotés un jour.


Avatar
Matthieu Moy
Thierry Noc writes:

En fait gcc 2.95 était trop intelligent,


GCC 2.95 faisait n'importe quoi avec la norme et te permetait de faire
du code pas portable du tout ...

avec la 3, il faut lui macher le boulot et encore il prend 4 fois
plus de temps pour compiler... bah je crois que je vais finir par
trouver les bons cotés un jour.


Pour le 3.4, rien que la qualité des messages d'erreur me suffit a le
trouver mieux que les précedants. Sinon, si tu cherches des avantages
par rapport a 2.95, regardes les perfs du code généré, par exemple ...

--
Matthieu

Avatar
Jean-Marc Bourguet
Thierry Noc writes:

J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
template (gcc 3.4.2):


Les erreurs (au moins avec Como) ont lieu aussi si la classe n'est pas
template. Une solution est de declarer et definir fn aussi a
l'exterieur de la classe (donc de le rendre template si besoin) de
rendre celui-la friend. Ce que suggere Xavier.

Ceci dit, j'aimerais poursuivre la discussion parce que je ne
comprends pas pourquoi ca foire. Le probleme est dans la recherche
des noms pour les fonctions friend declarees dans la classe.

extern void libfn(int(*)(int));


template <typename T>
class maclass {

friend int fn(int)
{
T var;
return(0);
}

void setup()
{
// libfn(fn); // OK avec gcc 2.95


C'est le comportement auquel je m'attendais. fn est friend et definie
dans la classe, donc inline et dans le scope de la classe. Que de
l'exterieur on ne puisse la trouver que par l'ADL -- et donc jamais
car il n'y a pas d'arguments de type adequat --, je comprend -- 5.1/7
a l'air de restreindre C::m aux membres --, mais de l'interieur de la
classe?

// libfn(fn); // `fn' undeclared (first use this
function)

// libfn(fn<T>); // `fn' undeclared (first use this
function)


Normal, fn n'est pas template.

libfn(::fn<T>); // `::fn' has not been declared


Idem.

}

};



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

| J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
| template (gcc 3.4.2):

Ça n'existe pas. Voir par exemple

http://www.cmla.ens-cachan.fr/~dosreis/C++/talks/type-of-toupper.pdf

| extern void libfn(int(*)(int));
|
|
| template <typename T>
| class maclass {
|
| friend int fn(int)
| {
| T var;
| return(0);
| }

cette construction réserve souvent des surprises :

(1) ce n'est pas une fonction template
(2) la seule manière d'appeler cette fonction est par
l'intermédiaire de « Koenig lookup.

En particulier un lookup normal ne peut pas la trouver d'où l'erreur.

|
| void setup()
| {
| // libfn(fn); // OK avec gcc 2.95
| // libfn(fn); // `fn' undeclared (first use this
| function)
| // libfn(fn<T>); // `fn' undeclared (first use this
| function)
| libfn(::fn<T>); // `::fn' has not been declared
| }
|
| };
|
| Une idée ?

Ta fonction fn n'a pas l'air de prendre un maclass<> en argument.
Pourquoi ne la fais-tu pas membre statique ?

-- Gaby
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Thierry Noc writes:
|
| > J'arrive pas a trouver la syntaxe pour obtenir l'adresse d'une fonction
| > template (gcc 3.4.2):
|
| Les erreurs (au moins avec Como) ont lieu aussi si la classe n'est pas
| template.

C'est un problème de lookup comme tu l'as dit.

[...]

| > template <typename T>
| > class maclass {
| >
| > friend int fn(int)
| > {
| > T var;
| > return(0);
| > }
| >
| > void setup()
| > {
| > // libfn(fn); // OK avec gcc 2.95
|
| C'est le comportement auquel je m'attendais. fn est friend et definie
| dans la classe, donc inline et dans le scope de la classe. Que de


Oui, mais quelqu'un a inventé des règles spéciales pour les friend :-(

Si tu déclares une fonction amie (sans nom qualifié), le compilateur
fait ceci :

(1) il regarde dans le namespace immédiatement englobant ;
s'il existe une déclaration correspondante, alors il la prend.


(2) Sinon, il introduit une déclaration invisible dans ce namespace.
Mais le nom reste invisible à la recherche de nom ordinaire.
Ceci jusqu'à ce qu'une déclaration correspondante ait été faite.

(3) s'il n'y a pas de déclaration correspondante, alors la seule
manière de référencer cette fonction est via la recherche de nom
dépendant de paramètres.

Voilà. Je ne suis pas convaincu que les règles pour les amis doivent
être aussi compliquées, mais va arguer cela avec CWG qui, à mon avis,
a tendance à préférer des règles avec 47 cas spéciaux aux règles
générales et uniformes.


| l'exterieur on ne puisse la trouver que par l'ADL -- et donc jamais
| car il n'y a pas d'arguments de type adequat --, je comprend -- 5.1/7
| a l'air de restreindre C::m aux membres --, mais de l'interieur de la
| classe?

C'est que la règle n'est pas formulée avec « de l'extérieur » ou
de « l'intérieur » :-). Mais j'avoue aussi ne pas savoir comment
interprèter ceci: 11.4/5

[...] A friend function defined in a class is in the (lexical)
scope of the class in which it is defined. A friend function
defined outside the class is not (3.4.1). 


Je crois que je vais commencer la journée par râler sur core ;-)

-- Gaby
Avatar
Jean-Marc Bourguet
Gabriel Dos Reis writes:

| l'exterieur on ne puisse la trouver que par l'ADL -- et donc jamais
| car il n'y a pas d'arguments de type adequat --, je comprend -- 5.1/7
| a l'air de restreindre C::m aux membres --, mais de l'interieur de la
| classe?


A relire 3.4.1/8 je vois pourquoi ce n'est pas trouve. J'ai du lire
trop vite avant d'ecrire.

C'est que la règle n'est pas formulée avec « de l'extérieur » ou de
« l'intérieur » :-). Mais j'avoue aussi ne pas savoir comment
interprèter ceci: 11.4/5

[...] A friend function defined in a class is in the (lexical)
scope of the class in which it is defined. A friend function
defined outside the class is not (3.4.1). 


Moi je l'avais compris comme quoi on pouvait trouver le nom quand on
cherchait dans la classe (et donc je m'attendais a ce que classe::ami
et ami sans qualification dans la classe le trouve). Mais en fait aux
deux endroits ou on fait une recherche dans le scope d'une classe
(5.1/7 et 3.4.1/8) on restreint cette recherche aux membres. Je me
demande si on n'a pas oublie en les ecrivant qu'il y avait ce cas tres
particulier des fonctions friend definies et declarees qui etait aussi
dans scope sans etre des membres. Je me souviens avoir ete d'abord
choque que l'ADL trouve qqch d'introuvable par qualification, et
maintenant en plus je vois que cette chose est introuvable dans le
scope sauf a cause de l'ADL. Une telle fonction, on peut l'appeler et
jamais prendre son adresse... Je me demande si c'est reellement
voulu.

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:

[...]

| dans scope sans etre des membres. Je me souviens avoir ete d'abord
| choque que l'ADL trouve qqch d'introuvable par qualification, et
| maintenant en plus je vois que cette chose est introuvable dans le
| scope sauf a cause de l'ADL. Une telle fonction, on peut l'appeler et
| jamais prendre son adresse... Je me demande si c'est reellement
| voulu.

J'ai donc soulévé le problème sur -core. On verra la suite.
John Spicer a rappelé deux vieux papiers (l'un discuté, l'autre pas)
relié å cette question. Je te ferai parvenir ces papiers (ou sur la
liste liste du groupe C++).

-- Gaby
1 2