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

Conditions sur des paramètres templates

16 réponses
Avatar
Yohan
Bonjour,

J'ai une question concernant les paramètres des classes templates.
Est-ce possible de déclarer une condition à remplir pour qu'un template
soit instancié (ou non)au moment de la compilation ?
(et donc que cette condition non remplie enverrait une erreur au
compilateur par exemple)
Et est-ce possible d'utiliser le même type de condition pour choisir
quel méthode le compilateur devra compiler.

L'exemple suivant illustre ma première question:
la condition serait "la variable nb est supérieure à 1"


template < class T, int nb >
class Foo
{
private:

T _tab[nb];

public:

Foo(T[nb]);

...

}


typedef Foo<float,2> Coord; // cette ligne doit pouvoir compiler

typedef Foo<int,3> Example; // cette ligne aussi

typedef Foo<float,0> Another; // mais j'aimerai que cette ligne
envoieune erreur au compilo


// Cet exemple concernait ma première question
Ma deuxième question concerne une condition qui permettrait au
compilateur de necompiler que certaines méthodes.
Le choix se fesant à la compilation...

Par exemple, le cas d'un nombre de paramètre variable avant comilation,
mais fixe après comilation:
Ce qui suit illustre la question:

template < class T, int nb >
class Foo2
{
private:

T _tab[nb];

public:

#if( nb==1 )
Foo(T t1);

#else if (nb==2)
Foo(T t1, T t2);

#else if....

...

}


// bien sur, la syntaxe est fausse, car le précompilateur ne connait pas
lavariable nb.
Donc mon idée aurait été de trouver une forme de condition sur les
variables template, évaluée au moment de la compilation.

Si vous avez uneidée, elle pourrait m'être très précieuse !

Merci


Yohan

10 réponses

1 2
Avatar
Fabien LE LEZ
On Wed, 22 Feb 2006 01:49:37 +0100, Yohan :

Est-ce possible de déclarer une condition à remplir pour qu'un template
soit instancié (ou non)au moment de la compilation ?


Il est possible que ceci réponde à ta question :
<http://www.google.com/search?&q=boost%20static_assert>

Avatar
Franck Branjonneau
Yohan écrivait:

J'ai une question concernant les paramètres des classes templates.
Est-ce possible de déclarer une condition à remplir pour qu'un
template soit instancié (ou non)au moment de la compilation ?


Ta question est mal posée.

Et est-ce possible d'utiliser le même type de condition pour choisir
quel méthode le compilateur devra compiler.


Cette question n'a pas de sens.

L'exemple suivant illustre ma première question:
la condition serait "la variable nb est supérieure à 1"


[ Je lis supérieure ou égale à 1 ]

template < class T, int nb >
class Foo
{
private:

T _tab[nb];


S'interdire l'usage de _ en premier caractère d'un identificateur.

public:

Foo(T[nb]);


Vraiment ?


...

}


Manque un point-virgule.

Quelque chose comme ça doit convenir :

template < class T, int nb, bool /* ensure nb >= 1 */ nb < 1 >
class Foo;

// Not defined, nb < 1 is true.
template<>
template < class T, int nb >
class Foo< T, nb, true >;


template<>
template < class T, int nb >
class Foo< T, nb, false > {

// Ok, nb >= 1.

};

typedef Foo<float,0> Another; // mais j'aimerai que cette ligne
envoieune erreur au compilo


Envoyer une erreur au compilateur ? Cette ligne provoqueras une erreur
de compilation et un diagnostic.

Ma deuxième question concerne une condition qui permettrait au
compilateur de necompiler que certaines méthodes.


Méthode ?

Le choix se fesant à la compilation...

Par exemple, le cas d'un nombre de paramètre variable avant
comilation, mais fixe après comilation:


Ce n'est pas évident. Voire du côté des tuples de boost ou tr1
peut-être.

Ce qui suit illustre la question:

template < class T, int nb >
class Foo2
{
private:

T _tab[nb];
^

Non !

public:

#if( nb==1 )
Foo(T t1);
^

2

#else if (nb==2)
Foo(T t1, T t2);
^

2

#else if....

...

}
^

;

Si le domaine de nombre est petit ou si le nombre de fonctions
concernées est petit il est possible de le faire « à la main ».

--
Franck Branjonneau

Avatar
meow
S'interdire l'usage de _ en premier caractère d'un identificateur.
pourquoi ?


Avatar
Franck Branjonneau
"meow" écrivait:

S'interdire l'usage de _ en premier caractère d'un identificateur.
pourquoi ?



Les noms commençant par _ sont réservés à l'implémentation.

--
Franck Branjonneau


Avatar
Fabien LE LEZ
On Thu, 23 Feb 2006 18:32:45 +0100, Franck Branjonneau
:

S'interdire l'usage de _ en premier caractère d'un identificateur.
pourquoi ?



Les noms commençant par _ sont réservés à l'implémentation.


En fait, pas tous -- mais c'est effectivement plus simple de
s'interdire tous les noms commençant par "_", ou contenant "__".

En théorie, on pourrait les utiliser comme membres d'une classe ; mais
en pratique, avec tous les #define qui traînent dans les headers,
c'est dangereux.

Note que s'interdire les noms commençant par "_" ne règle pas tous les
problèmes. Cf <http://www.gotw.ca/gotw/063.htm>.



Avatar
Fabien LE LEZ
On Thu, 23 Feb 2006 18:32:45 +0100, Franck Branjonneau
:

Les noms commençant par _ sont réservés à l'implémentation.


À l'implémentation de la bibliothèque standard.

Avatar
Franck Branjonneau
Fabien LE LEZ écrivait:

On Thu, 23 Feb 2006 18:32:45 +0100, Franck Branjonneau
:

Les noms commençant par _ sont réservés à l'implémentation.


À l'implémentation de la bibliothèque standard.


Non, à l'implémentation (17.4.3.1.2).

--
Franck Branjonneau


Avatar
meow
J'avoue que j'attendais vaguement une réponse du type de celle de
Fabien...

Celle là :
Non, à l'implémentation (17.4.3.1.2).
je la comprend moins ,O_o

qu'est-ce qu'on entend exactement par "l'implémentation" ?

Vu que je ne savais pas où chercher j'ai demandé à mon ami google
qui m'a donné quelques logs et forums dont je recopie ci dessous la
partie intéressante. Si donc j'ai bien compris, la norme (laquelle ?)
demande aux programmeurs C++ de n'utiliser les noms du genre "_miaou"
que dans le namespace global ou dans le namespace std:: (et une
classe... c'est considéré comme un namespace ?)

pour les noms du type "__miaou" ou "_Miaou" ils disent comme toi que
c'est "reservé à l'implémentation"... O_o
L'implémentation de quoi de qui ? Y manque rien dans cette phrase ?
Help !!!

17.4.3.1.2 of the Standard:
Certain sets of names and function signatures are always reserved to
the
implementation:
- Each name that contains a double underscore (_ _) or begins with an
underscore followed by an uppercase letter (2.11) is reserved to the
implementation for any use.
- Each name that begins with an underscore is reserved to the
implementation
for use as a name in the global namespace.165) Such names are also
reserved in namespace ::std (17.4.3.1).

Avatar
James Kanze
meow wrote:
J'avoue que j'attendais vaguement une réponse du type de celle de
Fabien...


Celle là :
Non, à l'implémentation (17.4.3.1.2).



je la comprend moins ,O_o qu'est-ce qu'on entend exactement par
"l'implémentation" ?


Ce qui est fourni par le compilateur. En général, il faut
entendre aussi le système d'exploitation, parce que le
compilateur (avec sa bibliothèque) en dépend.

Dans la pratique, il y a aussi parfois des logiciels tiers qui
en font partie aussi, mais strictement parlant, de point de vue
de la norme C++, ce sont des logiciels utilisateur exactement
comme le code que tu écris toi-même.

Vu que je ne savais pas où chercher j'ai demandé à mon ami
google qui m'a donné quelques logs et forums dont je recopie
ci dessous la partie intéressante. Si donc j'ai bien compris,
la norme (laquelle ?) demande aux programmeurs C++ de
n'utiliser les noms du genre "_miaou" que dans le namespace
global ou dans le namespace std:: (et une classe... c'est
considéré comme un namespace ?)


La norme, en l'occurance, c'est ISO 14882. La norme du langage
de programmation C++.

Et je crois que tu as compris à travers. Selon la norme, les
noms du genre « _miaou » sont reservés à l'implémentation au
niveau global -- tu peux théoriquement t'en servir comme membre
de classe, mais pas comme variable globale.

(Je dis théoriquement, parce que dans la pratique, ils posent
parfois des problèmes aussi comme membre de classe.)

pour les noms du type "__miaou" ou "_Miaou" ils disent comme
toi que c'est "reservé à l'implémentation"... O_o
L'implémentation de quoi de qui ?


L'implémentation du compilateur dont tu te sers, y compris tout
ce dont il dépend.

Y manque rien dans cette phrase ? Help !!!


C'est du « standardais » -- un dialect d'anglais un peu
particulier. En « standardais » (« standardois » ?
« standardien » ? -- « standardese » en anglais),
l'implémentation, c'est toujours l'implémentation de la norme,
c-à-d dans le cas d'une norme d'un langage du programmation, le
compilateur et l'environement qu'il fournit.

17.4.3.1.2 of the Standard:
Certain sets of names and function signatures are always
reserved to the implementation:
- Each name that contains a double underscore (_ _) or begins
with an underscore followed by an uppercase letter (2.11) is
reserved to the implementation for any use.


Surtout, en ce qui concerne le C++, une implémentation a droit
de définir des macros avec de tels noms. Alors, si tu t'en sers,
et l'implémentation a un macro prédéfini du même nom...

- Each name that begins with an underscore is reserved to the
implementation for use as a name in the global namespace.165)
Such names are also reserved in namespace ::std (17.4.3.1).


Ce qui exclut les macros (qui ne sont dans aucun espace
référentiel, mais qui vit dans un monde à part). C'est donc si
tu l'utilises dans espace référentiel global, tu risques des
conflits dans la définition, mais si tu t'en sers dans une
classe, ta définition cache celle de l'implémentation, ce qui ne
pose pas de problèmes.


Ça, c'est pour la théorie. Dans la pratique, ce n'est par rare
que l'implémentation comporte au moin un macro avec un nom du
genre « _miaou » (bien que la situation s'améliore nettement par
rapport au passé). Et ça, c'est dans le mode « compatible » ;
bien souvent, on veut aussi une compatibilité avec d'autres
normes aussi (Posix par exemple). Si je régarde Sun CC, par
exemple (ou g++ sous Solaris, je crois), en mode strictement
conforme, il n'y a pas de nom du genre « _miaou ». En
revanche, en mode strictement conforme, il n'y a ni de
threads ni de sockets non plus. Et dès que je passe en une mode
avec threads ou sockets, j'ai aussi quelques macros du genre
« _miaou ». Sous Linux, c'est pire -- dès que je sors du mode
conforme, j'ai un macro du nom « linux » (qui m'ennuie pas mal,
parce que j'ai un répertoire avec les en-têtes qui s'appelle
linux, et « #include "gb/syst/linux/xxx.hh" » ne marche pas très
bien quand tu remplaces linux avec 1).

--
James Kanze
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 Sat, 25 Feb 2006 15:49:11 +0100, James Kanze :

j'ai un macro du nom « linux » (qui m'ennuie pas mal,
parce que j'ai un répertoire avec les en-têtes qui s'appelle
linux, et « #include "gb/syst/linux/xxx.hh" » ne marche pas très
bien quand tu remplaces linux avec 1).


Comment t'en sors-tu dans ce cas ? Tu renommes le répertoire en
"Linux" ?

1 2