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

std_foreach et functor template

36 réponses
Avatar
jeremie fouche
Bonsoir

J'ai actuellement :

class C
{
private:
vector<Type*> m_vector;

public:
void clear(void)
{
for ( vector<Type*>::iterator i = m_vector.begin()
; i != m_vector.end()
; ++i
)
{
delete *i;
}
vector.clear();
}
};


je voulais changer le gros for en un std::for_each

1er essai :

void del(Type* ptr)
{
delete ptr;
}

void clear(void)
{
std::for_each(m_vector.begin(), m_vector.end(), del);
vector.clear();
}

Ca fonctionne !

2eme essai (car j'ai plusieurs conteneur de différent type) :

template <class T>
void del(T* ptr)
{
delete ptr;
}

void clear(void)
{
std::for_each(m_vector.begin(), m_vector.end(), del);
vector.clear();
}

Pouf, ca ne compile pas. Pourquoi la fonction template ne peut etre
créée pour la class Type* ?

Merci pour vos réponses
--
Jérémie

10 réponses

1 2 3 4
Avatar
James Kanze
On Dec 9, 1:59 pm, (Marc Espie) wrote:
In article
,
James Kanze wrote:

Historiquement, C++ a inventé les prototypes de fonctions, et
les a rendus obligatoire dès ses débuts : la seule écriture
légale était :
void clear() ;
En C, aussi, c'était la seule écriture légale, mais avec un
autre sémantique : ça signifiait qu'on ne donnait aucune
information en ce qui concerne les paramètres. (Je ne suis pas
sûr, mais je crois qu'on ne pouvait pas donner d'information
dans une declaration, seulement dans une définition.)


Oui, C se comportait comme un assembleur: on declare juste
qu'on utilise des symboles, avec extremement peu de controle
sur les symboles en question.


Même pas. Par défaut, un symbole qui est suivi d'un '(', c'est
déclaré implicitement comme une fonction qui renvoie un int (et
dont on ne sait rien en ce qui concerne le nombre et les types
des paramètres).

D'ailleurs, globalement, on utilise toujours des editeurs de
lien de cette epoque, d'ou le `name-mangling' pour encoder le
typage des fonctions qui est utilise par la plupart des
implementations de C++.


Les éditeurs de liens ont quand même évolués : sinon, on ne
pourrait pas faire des templates (qui ont besoin des symboles
<< weak >>). Sans parler des pré- et post-linkeurs dont se
servent beaucoup de compilateurs C++.

La raison qu'on est resté avec le mangling, alors que d'autres
solutions sont possibles, c'est d'abort pour la compatibilité
avec les anciens objets, et ensuite, parce que ça marchait, et
on a préféré investir des efforts ailleurs, où il le fallait
plus.

En fait, les prototypes n'existaient pas du tout en C
Kernighan et Richie, y compris pour les definitions de
fonctions, ou on ecrivait quelque chose tel que:

f(a)
int a;
{

}

(en l'absence de void, une fonction telle que f etait reputee
`traditionnellement' ne renvoyer rien, le compilateur jetant
un voile pudique sur le `int' implicite)


C'était bien plus ambigu que ça. C'était bien impossible à
déclarer une fonction qui renvoyait rien, mais on pouvait
renvoyer une valeur indéfinie pour l'int, qu'évidemment, le
client était sensé ignorer.

Et les conventions concernant l'utilisation de l'int implicit
variaient. Certains l'interdisaient complètement, d'autres la
préconcisaient systèmatiquement (ne jamais déclare l'int sur une
fonction), et d'autres la règle que tu donnes.

Aussi, on n'était pas toujours très cohérent entre la
définition (avec int explicit) et la déclaration (qu'on laissait
d'à coté la plupart du temps, si la fonction renvoyait int).

Le passage au C ANSI ne s'est pas fait sans douleur, puisque
les fonctions sans prototypes avaient des regles differentes
de coercion de type. Par exemple, impossible de passer un char
ou un float une fonction sans prototype, les arguments etant
d'office promu en int et double respectivement.

Ca a conduit a quelques-uns des pieges les plus vicieux du langage.
Ainsi, pour une definition de fonction en

f(a)
char a;
{
}

le prototype correspondant est bien
extern int f(int);

Ouch...

d'ou profonde rigolade lors de phases d'ansifications d'arbre source, vu
que le passage de l'un a l'autre n'est vraiment pas automatique.


Même avant. Je me rappelle bien avoir chercher longuement une
erreur parce que la fonction était définie :

char f( /* ... */ ) { /* ... */ }

et l'utilisateur n'avait pas de déclaration (et donc, le
compilateur supposait l'int implicit). Dans la fonction, le
compilateur ne générait du code que pour initialiser l'octet du
poid faible du régistre qui servait aux valeurs de retour,
tandis que le code utilisateur testait tout le régistre. (La
valeur était logiquement un bool.) On n'avait pas de
debuggueur, et quand j'ai inséré un fprintf juste avant le
retour dans la fonction, tout c'est mis à marcher. (Le fprintf
renvoyait un int, ici inférieur à 256, qui faisait que les trois
octets de poids fort du régistre était bien à zéro après sont
appel.)

Et ça, bien avant la norme ANSI du C.

et si on veut convertir *aussi* la definition de fonction, ca
ne donne rien de simple:

int
f(int a_)
{
char a = (char)a_;
}


La convertir en << int f( char ) >> était valide, à condition de
s'assurer que la nouvelle prototype était toujours en vue lors
de l'appel.

Bref, le comite a essaye de casser les choses le moins
possible tout en modernisant fortement le langage... certaines
des autres decisions (et leurs applications) sont encore plus
fourbes et ont poses encore plus de problemes (confere toute
la polemique autour de restrict, ou les decisions de certains
compilo `d'optimiser' les appels a memset qui `ne servent a
rien')

[...]

Ton resume de la suite est correct, mais il y manque un
element pedagogique.

C'est bien de permettre l'ecriture de void clear(void); en
C++, ca permet de simplifier les regles a retenir entre C et
C++.


C'est plus au moins essentiel, à mon avis, pour des en-têtes
partagés. Aujourd'hui, en tout cas ; dans la passée, on
utilisait quelque chose du genre :

int f( FUNCARGS(( int, double )) ) ;

ou FUNCARGS était définit à ne donner rien en C.

Meme si c'est pas `le plus propre' possible, je prefere dire
aux gens d'ecrire
void clear(void);
systematiquement, entre le C et le C++.
Tot ou tard, ils vont se retrouver a devoir utiliser les deux
langages,


Tôt ou tard, on serait amené à inclure les en-têtes en C. La
plupart des programmeurs C++, en revanche, n'écriront jamais une
ligne de C. (Ça fait au moins quinze ans depuis que j'ai écrit
quoique ce soit en C. Et je travaille en général à un niveau
assez bas et assez proche du système et du hardware.)

et cette syntaxe est la seule qui est sans surprise, et qui va
fonctionner sans devoir connaitre tous ces points de details
obscurs...


Ce syntaxe, c'est déjà un point de détail obscur:-).

--
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
James Kanze
On Dec 9, 10:38 pm, Fabien LE LEZ wrote:
On Sun, 9 Dec 2007 12:59:48 +0000 (UTC), (Marc Espie):

Meme si c'est pas `le plus propre' possible, je prefere dire
aux gens d'ecrire
void clear(void);
systematiquement, entre le C et le C++.


Bof... Ça contribue à alimenter le mythe qu'il y a un rapport
privilégié entre le C++ et le C.


Il y en a un : tu peux écrire un fichier d'en-tête qui
fonctionne avec les deux. Si tu veux accéder à des fonctions C
dans d'autres langages, il faut en général que tu transcrives
les déclarations de l'en-tête C dans l'autre langage.

Tot ou tard, ils vont se retrouver a devoir utiliser les deux langages,


Pas forcément ces deux-là en particulier.


Tôt ou tard, on va être amené à incorporer un en-tête C dans un
programme C++. Ne serait-ce que <windows.h> ou <unistd.h>.

Évidemment, ce n'est toujours pas une excuse pour bastardiser le
C++ quand on n'en a pas besoin. Et la plupart des programmeurs
nauront jamais à écrire un tel en-tête.

Pour la reste, je suis d'accord avec toi qu'on apprenne le C et
le C++ comme deux langages différents, avec leur propres règles,
et que les conventions du C n'influent pas sur la façon d'écrire
le C++ pur.

--
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
James Kanze
On Dec 9, 11:48 pm, Fabien LE LEZ wrote:

[...]
Le C++ est complexe pour une toute autre raison : il a plus de
fonctionnalités que n'importe quel autre langage.


Non seulement. Une des raisons principales pour sa manque de
simplicité et d'élégance, c'est qu'il se base sur le C. Sans ce
rapport avec le C, je suis sûr qu'il serait beaucoup plus simple
et plus élégant (encore que les problèmes de compatibilité entre
le C++ d'aujourd'hui, et celui du passée, exigeraient aussi des
compromis). Sans ce rapport, il serait aussi beaucoup moins
utilisé, vraiment beaucoup.

--
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
espie
In article ,
Fabien LE LEZ wrote:
Le C++ est complexe pour une toute autre raison : il a plus de
fonctionnalités que n'importe quel autre langage. À peu près tous les
paradigmes sont utilisables en C++ (même la programmation
fonctionnelle, avec les templates), ce qui donne une grande liberté,
mais aussi plus de responsabilités, au programmeur.


Pas seulement. Comme le dit James, la compatibilite avec le C le
complique assez furieusement.

Il y a aussi pas mal de details pas simples du tout... c'est un bon
langage, mais difficile a maitriser. Par exemple, il est relativement
peu enseigne de nos jours, parce que ca represente un volume d'heures
relativement important. C'est pas non plus le langage `de base' (on laisse
ca a Visual Basic et a java) parce que, malgre son extreme richesse, il
lui manque un ensemble d'outils a peu pres standards pour, par exemple,
faire du graphique... (je crains que qt soit arrive trop tard pour changer
ca).

Je sais que, pour ma pomme, c'est un langage que j'ai decouvert tres tard
dans mes etudes, apres etre tombe sur un Stroustrup une premiere fois,
avoir lu quelques chapitres, et trouve qu'il y avait vraiment beaucoup
trop de regles dans ce langage... la 2e fois, ca c'est beaucoup mieux passe.
Faut dire que la 3e edition est nettement plus lisible, mais je comprend le
point de vue du debutant.

Meme si java possede plein d'autres defauts, commercialement ils ont mieux
presente leur langage: on commence avec des trucs simples, on te dit que
le langage est tout gentil. Et c'est seulement lorsque tu commences a
vouloir faire des vrais trucs que tu te rends compte qu'il y a plein de
subtilites a la noix (et que c'est nettement plus crade que le C++).
Mais la learning curve en est une, de courbe. Au contraire du C++, qui
presente une falaise a pic de 150m, avec quelques rares asperites auxquelles
s'accrocher...

Avatar
Gabriel Dos Reis
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--8323584-1481807240-1197335344=:3894
Content-Type: TEXT/PLAIN; charset=UTF-8
Content-Transfer-Encoding: 8BIT

On Sun, 9 Dec 2007, Fabien LE LEZ wrote:

| On Sun, 9 Dec 2007 22:08:14 +0000 (UTC), (Marc Espie):
|
| >>Bof... Ça contribue à alimenter le mythe qu'il y a un rapport
| >>privilégié entre le C++ et le C.
| >
| >C'est pas un mythe !
|
| Ah bon ?

Oui.

-- Gaby
--8323584-1481807240-1197335344=:3894--
Avatar
Gabriel Dos Reis
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--8323584-923499614-1197335521=:3894
Content-Type: TEXT/PLAIN; charset=UTF-8
Content-Transfer-Encoding: 8BIT

On Mon, 10 Dec 2007, James Kanze wrote:

| On Dec 9, 11:48 pm, Fabien LE LEZ wrote:
|
| [...]
| > Le C++ est complexe pour une toute autre raison : il a plus de
| > fonctionnalités que n'importe quel autre langage.
|
| Non seulement.

Well, il y a Perl :-/

| Une des raisons principales pour sa manque de
| simplicité et d'élégance, c'est qu'il se base sur le C. Sans ce
| rapport avec le C, je suis sûr qu'il serait beaucoup plus simple
| et plus élégant (encore que les problèmes de compatibilité entre
| le C++ d'aujourd'hui, et celui du passée, exigeraient aussi des
| compromis). Sans ce rapport, il serait aussi beaucoup moins
| utilisé, vraiment beaucoup.

Note cependant que d'autres langages comme Java on Ada n'ont pas ce
poids de compatibilité avec le C, mais sont quand même assez complexes
(au moins aussi complexe que C++).

-- Gaby
--8323584-923499614-1197335521=:3894--
Avatar
Michael DOUBEZ
On Mon, 10 Dec 2007, James Kanze wrote:

| On Dec 9, 11:48 pm, Fabien LE LEZ wrote:
|
| [...]
| > Le C++ est complexe pour une toute autre raison : il a plus de
| > fonctionnalités que n'importe quel autre langage.
|
| Non seulement.

Well, il y a Perl :-/


Eh bien si il y a plus d'une façon de tuer un chat, perl les a toutes
... en même temps.

Il y a aussi l'académique Oz qui supporte en plus la programmation
logique je crois. Le nombre de paradigmes supporté n'est pas un critère
de réussite (quoi que Oz n'a jamais eu cette vocation).
Ce que j'aime dans le C++ est son coté pragmatique: quelque chose n'et
pas en standard parceque ça fait beau mais parceque, en général, c'est
utile.


| Une des raisons principales pour sa manque de
| simplicité et d'élégance, c'est qu'il se base sur le C. Sans ce
| rapport avec le C, je suis sûr qu'il serait beaucoup plus simple
| et plus élégant (encore que les problèmes de compatibilité entre
| le C++ d'aujourd'hui, et celui du passée, exigeraient aussi des
| compromis). Sans ce rapport, il serait aussi beaucoup moins
| utilisé, vraiment beaucoup.

Note cependant que d'autres langages comme Java on Ada n'ont pas ce
poids de compatibilité avec le C, mais sont quand même assez complexes
(au moins aussi complexe que C++).


AMA, le langage Java en lui même n'est pas très difficile à apprendre.
Ce qui prends du temps est la tonne de bibliothèques, frameworks et
patterns associés sans lesquels Java perd beaucoup de son intérêt.

Michael

Avatar
Ael Rowan Terence
"Gabriel Dos Reis" a écrit dans le message de
news:
On Sun, 9 Dec 2007, Fabien LE LEZ wrote:

| On Sun, 9 Dec 2007 22:08:14 +0000 (UTC), (Marc Espie):
|
| >>Bof... Ça contribue à alimenter le mythe qu'il y a un rapport
| >>privilégié entre le C++ et le C.
| >
| >C'est pas un mythe !
|
| Ah bon ?

Oui.


Ha ! enfin le retour.

Signer : un fervant lecteur.

Avatar
James Kanze
On Dec 11, 2:12 am, Gabriel Dos Reis wrote:
On Mon, 10 Dec 2007, James Kanze wrote:

| On Dec 9, 11:48 pm, Fabien LE LEZ wrote:

| [...]
| > Le C++ est complexe pour une toute autre raison : il a plus de
| > fonctionnalités que n'importe quel autre langage.

| Non seulement.

Well, il y a Perl :-/


C'est vrai. Comme quoi, avec un peu d'effort, on peut donner
même à C++ l'air d'être simple et élégant en comparaison.

| Une des raisons principales pour sa manque de
| simplicité et d'élégance, c'est qu'il se base sur le C. Sans ce
| rapport avec le C, je suis sûr qu'il serait beaucoup plus simple
| et plus élégant (encore que les problèmes de compatibilité entre
| le C++ d'aujourd'hui, et celui du passée, exigeraient aussi des
| compromis). Sans ce rapport, il serait aussi beaucoup moins
| utilisé, vraiment beaucoup.

Note cependant que d'autres langages comme Java on Ada n'ont pas ce
poids de compatibilité avec le C, mais sont quand même assez complexes
(au moins aussi complexe que C++).


Dans le cas d'Ada, je crois qu'il supporte même plus de
fonctionnalités que le C++ (les threads, par exemple). Et sans
être simple, il évite certains problèmes. (Les déclarations, par
exemple, sont en général facile à lire et à écrire, et jamais
ambiguës.)

Dans le cas de Java, évidemment : on a un langage qui s'est
basé sur C. Pourquoi, par exemple, sans la contrainte de la
compatilibilité, il n'a pas répensé la syntaxe des
déclarations ?

--
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
Fabien LE LEZ
On Tue, 11 Dec 2007 00:47:57 -0800 (PST), James Kanze
:

Well, il y a Perl :-/


C'est vrai. Comme quoi, avec un peu d'effort, on peut donner
même à C++ l'air d'être simple et élégant en comparaison.


J'ai essayé d'utiliser, dans bash, des fonctions capables de renvoyer
une valeur. C'est mignon aussi.


1 2 3 4