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

Editer du C++ template avec un editeur de texte

138 réponses
Avatar
Marc Boyer
Bonjour,

une petite question sur vos pratiques d'édition.

Pour écrire la définition de code de classe template, j'aimerais
bien séparer l'interface de l'implémentation.

Mais ça devient très lourd, du genre

template <class T>
typename X<T>::iterator X<T>::first_with(typename X<T>::cond& c){
....
}

alors que si je laisse dans la déclaration de la classe, ça donne
iterator first_with(cond& c);

Je m'en sort à grands coups de
#define X_TEMPLATE template<class T>
#define X X<T>
#define iterator typename X<T>::iterator
#define cond typename X<T>::cond

mais c'est lourd.

Vous faites comment vous ? Un super éditeur/IDE qui cache tout le sucre ?


Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle pas
de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.

10 réponses

1 2 3 4 5
Avatar
Fabien LE LEZ
On 15 Nov 2004 10:31:27 GMT, Marc Boyer
:

Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle pas
de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}


Quelle pourrait en être l'utilité ?


--
;-)

Avatar
Marc Boyer
In article , Fabien LE LEZ wrote:
On 15 Nov 2004 10:31:27 GMT, Marc Boyer
:

Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle pas
de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}


Quelle pourrait en être l'utilité ?


Pouvoir séparer interface et implémentation dans le ficher:
au début de la classe, toutes les déclarations de fonctions
membres, et les définitions de type et variable, puis les
implémentations en fin de fichier.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
Fabien
Si tu regardes comment bossent les grands groupes d'édition de logiciels
(génère du code natif JNI par exemple ou ouvre le src d'Apache HTTP
Server), tu verras que tout le monde y va à grand coup de #define.
C'est que cette solution ne doit pas être des plus mauvaises...

@+ Fabien

Marc Boyer wrote:
Bonjour,

une petite question sur vos pratiques d'édition.

Pour écrire la définition de code de classe template, j'aimerais
bien séparer l'interface de l'implémentation.

Mais ça devient très lourd, du genre

template <class T>
typename X<T>::iterator X<T>::first_with(typename X<T>::cond& c){
....
}

alors que si je laisse dans la déclaration de la classe, ça donne
iterator first_with(cond& c);

Je m'en sort à grands coups de
#define X_TEMPLATE template<class T>
#define X X<T>
#define iterator typename X<T>::iterator
#define cond typename X<T>::cond

mais c'est lourd.

Vous faites comment vous ? Un super éditeur/IDE qui cache tout le sucre ?


Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle pas
de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}

Marc Boyer


Avatar
drkm
Fabien writes:

tu verras que tout le monde y va à grand coup de #define.
C'est que cette solution ne doit pas être des plus mauvaises...


Je ne vois pas le rapport.

--drkm

Avatar
Marc Boyer
Fabien wrote:
Si tu regardes comment bossent les grands groupes d'édition de logiciels
(génère du code natif JNI par exemple ou ouvre le src d'Apache HTTP
Server), tu verras que tout le monde y va à grand coup de #define.


OK.

C'est que cette solution ne doit pas être des plus mauvaises...


J'avoue qu'en fait, je rève d'un bel IDE qui masque un peut
tout ce sucre: je sélectionne une classe, j'accède à sa définition,
son implémentation, ses spécialisation, tout ça bien rangé...

Je vais tester VC++ un de ces jours pour voir.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.

Avatar
kanze
Marc Boyer wrote in message
news:<cna0hv$4qo$...

une petite question sur vos pratiques d'édition.

Pour écrire la définition de code de classe template, j'aimerais bien
séparer l'interface de l'implémentation.

Mais ça devient très lourd, du genre

template <class T>
typename X<T>::iterator X<T>::first_with(typename X<T>::cond& c){
....
}


C'est lourd. Le C++ exige en effet beaucoup de boilerplate.

Note toutefois qu'un peu de rédondance n'est pas forcement une mauvaise
chose.

alors que si je laisse dans la déclaration de la classe, ça donne
iterator first_with(cond& c);


Ça donne surtout un très fort couplage des fichiers, ce qui devient vite
insoutenable dans les grands projets.

Je m'en sort à grands coups de
#define X_TEMPLATE template<class T>
#define X X<T>
#define iterator typename X<T>::iterator
#define cond typename X<T>::cond


J'espère que non. J'appelle ça l'obfuscation.

mais c'est lourd.

Vous faites comment vous ? Un super éditeur/IDE qui cache tout le
sucre ?


Je ne sais pas si c'est un super éditeur, mais les deux éditeurs dont je
me sers (vim et emacs) ont tous les deux l'achevement automatique des
mots, ce qui réduit de beaucoup le nombre de caractères à entrée. Sinon,
les deux supportent aussi la copier/coller, et l'enregistrement d'un
bout de texte dans un régistre nommé, quand j'ai une suite de fonctions
avec un en-tête en commun.

Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle
pas de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}


Parce que ça n'apportera rien, dans la mésure où le but, c'est que
l'implémentation et la définition de la classe soient dans des fichiers
distincts.

Ce que j'avais suggéré, à une époque, c'est la possibilité de définir
des portées d'implémentations, quelque chose du genre :

implement class X {
// ...
}

où toutes les fonctions définies dans la portée aurait appartenues à
class X. Étendu à ton exemple, ça aurait donné :

implement template< typename T > class X< T >
{
iterator first_with( cond& c ) { ... }
}

(À l'époque où j'y avais pensé, il n'y avait pas encore le typename dans
les templates.)

J'avais pensé aussi qu'il pourrait aussi être intéressant de permettre
la declaration et la définition de nouvelles fonctions privées (non
virtuelles) dans ce contexte.

J'en avais parlé à plusieurs personnes dans une réunion du comité ;
suite à la manque manifeste d'intérêt, j'ai laissé tomber.

--
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
Marc Boyer
wrote:
Marc Boyer wrote in message
news:<cna0hv$4qo$...

une petite question sur vos pratiques d'édition.

Pour écrire la définition de code de classe template, j'aimerais bien
séparer l'interface de l'implémentation.

Mais ça devient très lourd, du genre

template <class T>
typename X<T>::iterator X<T>::first_with(typename X<T>::cond& c){
....
}


C'est lourd. Le C++ exige en effet beaucoup de boilerplate.

Note toutefois qu'un peu de rédondance n'est pas forcement une mauvaise
chose.


Je vois bien que tout est important dans tout cela, mais dans
un contexte donné, ça fait redondance.

alors que si je laisse dans la déclaration de la classe, ça donne
iterator first_with(cond& c);


Ça donne surtout un très fort couplage des fichiers, ce qui devient vite
insoutenable dans les grands projets.


Tu peux préciser ?

Je m'en sort à grands coups de
#define X_TEMPLATE template<class T>
#define X X<T>
#define iterator typename X<T>::iterator
#define cond typename X<T>::cond


J'espère que non. J'appelle ça l'obfuscation.


Fabien semblait dire que j'étais pas le seul.

mais c'est lourd.

Vous faites comment vous ? Un super éditeur/IDE qui cache tout le
sucre ?


Je ne sais pas si c'est un super éditeur, mais les deux éditeurs dont je
me sers (vim et emacs) ont tous les deux l'achevement automatique des
mots, ce qui réduit de beaucoup le nombre de caractères à entrée. Sinon,
les deux supportent aussi la copier/coller, et l'enregistrement d'un
bout de texte dans un régistre nommé, quand j'ai une suite de fonctions
avec un en-tête en commun.


C'est pas tellement la frappe qui me dérange que la relecture.

Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle
pas de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}


Parce que ça n'apportera rien, dans la mésure où le but, c'est que
l'implémentation et la définition de la classe soient dans des fichiers
distincts.


Moi, déjà, si je pouvais voir la signature de ma classe rapidement
(sans avoir à passer par doxygen puis à revenir à xemacs...) se
serait pas mal.


Ce que j'avais suggéré, à une époque, c'est la possibilité de définir
des portées d'implémentations, quelque chose du genre :

implement class X {
// ...
}

où toutes les fonctions définies dans la portée aurait appartenues à
class X. Étendu à ton exemple, ça aurait donné :

implement template< typename T > class X< T >
{
iterator first_with( cond& c ) { ... }
}

(À l'époque où j'y avais pensé, il n'y avait pas encore le typename dans
les templates.)


Je ne sais pas quels problèmes cela introduirait, mais ça résoudrait
les miens ;-)

J'avais pensé aussi qu'il pourrait aussi être intéressant de permettre
la declaration et la définition de nouvelles fonctions privées (non
virtuelles) dans ce contexte.

J'en avais parlé à plusieurs personnes dans une réunion du comité ;
suite à la manque manifeste d'intérêt, j'ai laissé tomber.


Ah... Dommage...

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
K. Ahausse
"Marc Boyer" a écrit dans le message
de news:cnccv0$jla$
Fabien wrote:
Si tu regardes comment bossent les grands groupes d'édition de logiciels
(génère du code natif JNI par exemple ou ouvre le src d'Apache HTTP
Server), tu verras que tout le monde y va à grand coup de #define.


OK.

C'est que cette solution ne doit pas être des plus mauvaises...


J'avoue qu'en fait, je rève d'un bel IDE qui masque un peut
tout ce sucre: je sélectionne une classe, j'accède à sa définition,
son implémentation, ses spécialisation, tout ça bien rangé...

Je vais tester VC++ un de ces jours pour voir.


La touche 'F12' ( le browser de VC++ ) se positionne directement sur la
définition du symbole choisi (macro, variable, fonction, class, attribut,
méthode,...) Et c'est purement magique. L'écriture ET la mise au point de
programme atteint un confort, que je n'ai connu qu'avec les suites de
développement MS.

Sous Linux je n'ai pas trouvé un IDE qui rivalise.( Je n'ai pas, non plus,
réaliser un test exhaustif de toutes les solutions envisageables, cela
demanderai un investissement en temps prohibitif ).

Même, pour l'écriture d'application Linux j'utilise VC++, après quelques
tentatives désastreuses ( Kdevelop, notamment) avec des solutions propre à
Linux.
J'ai paramètre VC++ pour éditer et compiler les sources d'un serveur Linux,
et pour la mise au point j'utilise 'insight'.
L'avantage que je trouve dans cette configuration est de pouvoir ré-utiliser
les macros de VC++ que j'ai ajouté, initialement, pour Windows.Et ça aussi,
c'est géant, les macro de VC++.


Avatar
Marc Boyer
wrote:
Je m'en sort à grands coups de
#define X_TEMPLATE template<class T>
#define X X<T>
#define iterator typename X<T>::iterator
#define cond typename X<T>::cond


J'espère que non. J'appelle ça l'obfuscation.


Pour donner un exemple issu de mon code, sans macro, cela donne:

template<class FSM, template <class, class> class NodeCont,
template <class, class> class ArcCont>
typename StateSpace<FSM, NodeCont, ArcCont>::statespace_arc_iterator
StateSpace<FSM, NodeCont, ArcCont>::arcsBegin() {
.....
}

template<class FSM, template <class, class> class NodeCont,
template <class, class> class ArcCont>
bool
StateSpace<FSM, NodeCont, ArcCont>::find(
const typename StateSpace<FSM, NodeCont, ArcCont>::NodeInfo& info,
typename StateSpace<FSM, NodeCont, ArcCont>::StateSpaceNode* &theNode) {
.....
}

et avec macros

SS_TEMPLATE
statespace_arc_iterator STATE_SPACE::arcsBegin() {
....
}

SS_TEMPLATE
bool STATE_SPACE::find(const NodeInfo& info, StateSpaceNode* &theNode) {
....
}

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
Jean-Marc Bourguet
writes:

Je ne sais pas si c'est un super éditeur, mais les deux éditeurs dont je
me sers (vim et emacs) ont tous les deux l'achevement automatique des
mots, ce qui réduit de beaucoup le nombre de caractères à entrée. Sinon,
les deux supportent aussi la copier/coller, et l'enregistrement d'un
bout de texte dans un régistre nommé, quand j'ai une suite de fonctions
avec un en-tête en commun.


Dans un projet precedant, nous avions du lisp qui prenait une
definition de classe et creait des stubs pour l'implementation des
membres (en gerant en prime nos conventions pour les commentaires).
Mais c'etait complique a utilise, surtout quand on ne faisait que
modifier. J'ai tendance ces derniers temps a faire comme toi et
utiliser les registres d'emacs.

Si Marc veut en plus cacher ca (et donc ne pas simplement pouvoir le
creer plus facilement), il doit y avoir moyen avec emacs (on peut
tout) mais j'ai rien vu.

Regarde aussi peut-etre eclipse. Ils se vantent d'avoir un
"refactoring editor" (ce qui doit comprendre au moins la possibilite
de renommer de maniere intelligente et d'ajouter des parametres
templates). Mais leur conception de projet etait trop restrictive
pour moi la derniere fois que j'ai regarde, j'ai meme pas ete jusqu'a
experimenter avec ces possibilites, il aurait fallu commencer par
modifier tout mon systeme de build...

Et sinon, pourquoi les classes (enfin, mon compilo) ne permettent elle
pas de faire

class X {
void foo(); // Déclaration
...
void foo(){...}; // Implementation
}


Parce que ça n'apportera rien, dans la mésure où le but, c'est que
l'implémentation et la définition de la classe soient dans des fichiers
distincts.

Ce que j'avais suggéré, à une époque, c'est la possibilité de définir
des portées d'implémentations, quelque chose du genre :

implement class X {
// ...
}

où toutes les fonctions définies dans la portée aurait appartenues à
class X. Étendu à ton exemple, ça aurait donné :

implement template< typename T > class X< T >
{
iterator first_with( cond& c ) { ... }
}

(À l'époque où j'y avais pensé, il n'y avait pas encore le typename dans
les templates.)

J'avais pensé aussi qu'il pourrait aussi être intéressant de permettre
la declaration et la définition de nouvelles fonctions privées (non
virtuelles) dans ce contexte.


Et des membres statiques aussi je suppose?

J'en avais parlé à plusieurs personnes dans une réunion du comité ;
suite à la manque manifeste d'intérêt, j'ai laissé tomber.


Ce serait interessant de voir quelles seraient les reactions
maintenant. Et aussi de voir comment ca se combime avec la
proposition de David sur les modules.

Elle m'a l'air -- je n'ai fait que survoler -- d'aller dans le sens
d'une fusion interface/implementation comme en Java. Je ne suis pas
sur que j'aime cette caracteristique:
- le fichier d'interface est trop souvent la seule documentation,
l'enlever me gene et devoir chercher ce qui sera eparpille dans
le fichier d'implementation ne m'attire pas.
- il est relativement courant d'avoir plusieurs implementations
pour la meme interface, partager le meme fichier definissant
celle-ci permet au compilateur de s'assurer de la coherence
- j'aime assez bien l'idee -- meme si je ne suis pas dans un
environnement ou elle est applicable -- d'avoir un controle (au
niveau CM) different sur les interfaces.
Les modules sont surtout utiles dans les gros projets, cette fusion me
semble surtout pertinante pour les petits.

Une autre chose, c'est qu'une lecture rapide donne l'impression que
les types mutuellement recursifs entre modules vont poser probleme.
Ada avait ce probleme et l'enlever est un des points sur lequel la
prochaine norme va changer le langage. Ce serait bete de faire la
meme chose en C++.

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


1 2 3 4 5