templates et définitions

Please use this forum to ask for a new feature or to change an existing feature.
Merci d'utiliser ce forum pour demander de nouvelles fonctionnalités ou la modification de fonctionnalités existantes.

templates et définitions

Postby Teaniel » Sun 4 Nov 2012 17:02

Bonjour,

Au chapitre des nouveautés de C++11, en rapport avec les fonctions et classes génériques, il n'est plus nécessaire de présenter toute la définition de la classe à son utilisateur.
On peut maintenant se comporter avec ces fonctions comme avec les fonctions normales (une déclaration externe dans le .h et la définition dans le .cpp).
Dans ce cadre là, je pense qu'il n'est plus nécessaire de forcer la propriété inline des fonctions des classes template (pour l'instant elle est grisée dans l'interface).

Cordialement,
Marc
Teaniel
 
Posts: 75
Joined: Sun 28 Oct 2012 18:57

Re: templates et définitions

Postby Bruno Pagès » Mon 5 Nov 2012 15:50

Bonjour,

là je ne suis pas d'accord, une opération utilisant un paramètre formel doit impérativement être définie dans le fichier d'en-tête
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 440
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: templates et définitions

Postby Teaniel » Tue 6 Nov 2012 19:53

Bonjour,

Ben... Je vous propose d'essayer. C'est ce que j'ai fait avant de poster cette demande, avec QT et g++.
J'ai créé une classe générique, comme d'habitude, en la mettant (déclaration et définitions) dans le header.
Après avoir lu un truc (désolé je ne me rappelle plus où tout ce que je me souviens c'est que c'était en anglais) sur le sujet, ça m'a pris d'essayer, en déplaçant toutes les définitions des fonctions de ma classe dans le .cpp, et tout a fonctionné. J'ai pu vérifier dans le debugger que je passais bien dans les fonctions que j'avais ainsi définies.
Je vais, pour bétonner, refaire un essai en créant un projet spécialement pour ça et je vous tiens au courant.

Cordialement,
Marc
Teaniel
 
Posts: 75
Joined: Sun 28 Oct 2012 18:57

Re: templates et définitions

Postby Teaniel » Wed 7 Nov 2012 12:26

Bonjour,

Veuillez accepter mes excuses, en effet je n'arrive pas à reproduire ce que j'ai fait.
J'avais pris l'info ici, et l'ai mal interprétée: http://en.wikipedia.org/wiki/C%2B%2B11#Extern_template
A l'endroit où elles sont instanciées, les classes doivent toujours être complètement définies.
Ceci dit, ce que j'ai indiqué avoir fait dans le post précédent, je l'ai réellement fait, et je n'ai pas encore compris pourquoi ça marche. A aucun moment je n'instancie explicitement la classe que j'ai développée, et j'ai effectivement déplacé la définition des fonctions dans le cpp.
De fait, si on externalise les fonctions, il semble qu'il soit obligatoire d'y ajouter une instanciation explicite sans quoi on se prend une erreur type 'référence à fonction maclasse<int>::maclasse() non définie'.
Finalement, en utilisant le mot-clé extern qui permet d'empêcher l'instanciation immédiate, et l'instanciation explicite dans le cpp, on peut effectivement écrire les classes template comme je le souhaite (simplement, dans ce cas là, on limite l'utilisation de la classe aux génériques instanciés, sans permettre à l'utilisateur d'en créer de nouveaux).
Et c'est la raison pour laquelle, si vous voulez bien, je maintiens ma demande.

Cordialement,
Marc
Teaniel
 
Posts: 75
Joined: Sun 28 Oct 2012 18:57

Re: templates et définitions

Postby Bruno Pagès » Wed 7 Nov 2012 13:36

Bonjour,

je ne comprends pas ce que vous voulez dire, pouvez vous donner un exemple de code à générer ?
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 440
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: templates et définitions

Postby Teaniel » Wed 7 Nov 2012 14:38

Bien sur :)

header a.h:
Code: Select all
template <class T> class A {
    T p;
    public:
    A();
};
// Déclaration n'impliquant pas l'instanciation des classes.
extern template class A<int>;
extern template class A<double>;

source a.cpp:
Code: Select all
template <class T> A<T>::A() : p() {}

// Ici on instancie les template :
template class A<int>;
template class A<double>;

utilisation :
Code: Select all
#include "A.h"

...
A<int> Aint;
...
A<double> Adouble;
...


Voila exactement ce que je souhaitais pouvoir faire.
Je comprends bien que cela implique et n'est réalisable que si je connais exhaustivement les types que cette classe utilisera. En effet, le fait de cacher la définition des fonctions à l'utilisateur signifie que celui-ci ne pourra pas en générer d'autres. Dans mon projet c'est parfaitement assumé.
Notez que cela fonctionnait déjà avant c++11, sauf que le mot clé extern ne pouvant être utilisé, l'instanciation se faisait à chaque point d'utilisation. extern apporte un gain de performances au compilateur.

Voila pourquoi je souhaiterais pouvoir décocher la case 'inline' dans la définition d'une fonction membre de classe paramétrée. :)

Cordialement,
Marc
Teaniel
 
Posts: 75
Joined: Sun 28 Oct 2012 18:57

Re: templates et définitions

Postby Bruno Pagès » Wed 7 Nov 2012 16:01

mais le constructeur pourrait tout aussi bien être défini dans le fichier d'en-tête, ce qui n'occasionne pas instanciation supplémentaire dans votre cas

la seule différence que je vois est que dans votre cas il est impossible de faire une instanciation avec un paramètre actuel autre que int et double car cela produirai une erreur à l'édition de liens, c'est ca le but ultime de la chose ?
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 440
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: templates et définitions

Postby Teaniel » Wed 7 Nov 2012 18:17

Bonjour,

Ça pourrait l'être, en effet.
Mon objectif est surtout de ne pas être obligé de présenter les définitions des fonctions au client (en particulier dans les cas où on se retrouve avec des dépendances cycliques).
Exemple où cette construction m'est indispensable (exemple minimaliste):
Code: Select all
template <class T> class base {
public:
   static base *Create(int i);// i me sert de sélecteur de construction, il peut être n'importe quoi
};

template <class T> class derivee1 : public base<T> {};
template <class T> class derivee2 : public base<T> {};
template <class T> class derivee3 : public base<T> {};
template <class T> class derivee4 : public base<T> {};

base *base::Create(int i) {
    switch(i) {
        case 1: return new derivee1;
        case 2: return new derivee2;
        case 3: return new derivee3;
...
   }
}

main() {
...
base<double> *obj = base<double>::Create(3);
...
}

Dans ce cas, Create ne peut être inclus dans le header si les classes dérivées n'y sont pas aussi (cas de l'organisation 1 classe = 1 artifact).
Egalement Create est obligé de connaître toutes les classes qu'il doit créer. On se retrouve donc ici avec une dépendance cyclique. Par conséquent, cette fonction ne peut être définie ailleurs que dans un .cpp.
C'est très précisément dans cette situation que je me trouve dans mon projet.

Voila.
Cordialement,
Marc
Teaniel
 
Posts: 75
Joined: Sun 28 Oct 2012 18:57

Re: templates et définitions

Postby Bruno Pagès » Thu 8 Nov 2012 07:25

Bonjour,

ah oui, je n'avais pas pensé aux cycles

je vais rendre modifiable l'option inline dans le cas d'une opération dans une classe paramétrée. Bien évidemment la première fois que l'on ajoutera des paramètres formels à une classe cela forcera inline pour ses opérations, et par défaut une opération ajoutée à une classe paramétrée sera également inline.

cela implique aussi la modification du générateur, et des reverse/roundtrip (en plus de la correction du cas && dans les paramètres pour ces derniers).
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 440
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: templates et définitions

Postby Bruno Pagès » Sun 2 Dec 2012 22:03

La version 6.4 est disponible, l'option inline peut maintenant être décochée pour les opérations des classes paramétrées.
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 440
Joined: Mon 20 Feb 2012 08:23
Location: France


Return to Change requests / Demandes d'évolution

Who is online

Users browsing this forum: No registered users and 1 guest

cron