OVH Cloud OVH Cloud

Specialisation template

7 réponses
Avatar
Vincent Lascaux
Bonjour,

Le code suivant ne compile pas sous visual studio .net. Est ce normal ?
Y-a-t'il une astuce pour contourner le probleme ?

#include <utility>
template<class T> void foo(T) {}
template<class A, class B> void foo< std::pair<A,B> >(std::pair<A,B>) {}

Erreur : error C2768: 'foo' : utilisation non conforme d'arguments de modèle
explicite

Merci

--
Vincent

7 réponses

Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| Bonjour,
|
| Le code suivant ne compile pas sous visual studio .net. Est ce normal ?

Oui.

| Y-a-t'il une astuce pour contourner le probleme ?

Yep. Surcharge.

| #include <utility>
| template<class T> void foo(T) {}
| template<class A, class B> void foo< std::pair<A,B> >(std::pair<A,B>) {}
|
| Erreur : error C2768: 'foo' : utilisation non conforme d'arguments de modèle
| explicite

template<class T>
void foo(T) { }

template<class A, class B>
void foo(std::pair<A, B>) { }


Les fonctions template peuvent être spécialisées explicitement ; mais,
à l'inverse des classes templates, elles ne peuvent être spécialisées
partiellement.

-- Gaby
Avatar
Vincent Lascaux
template<class T>
void foo(T) { }

template<class A, class B>
void foo(std::pair<A, B>) { }


Effectivement, ca marche...

Les fonctions template peuvent être spécialisées explicitement ; mais,
à l'inverse des classes templates, elles ne peuvent être spécialisées
partiellement.


Est ce que tu peux préciser la difference entre ces deux spécialisations ?

--
Vincent

Avatar
Arnaud Debaene
Vincent Lascaux wrote:


Est ce que tu peux préciser la difference entre ces deux
spécialisations ?


template<class T> void foo(T) {}
template<class A, class B> void foo< std::pair<A,B> >(std::pair<A,B>) {}

La première ligne est la définition générale de la fonction : aucune
spécialisation, T peut être n'importe quoi.

La deuxième ligne définit un sous-ensemble des types T possibles pour la
1ère ligne : l'ensemble des std::pair<A, B>. C'est une spécialisation
partielle de foo car elle s'applique à un sous-ensemble (template) de
l'ensemble de spécialisations possibles de foo.

Les spécialisations partielles sont autorisées pour les classes, pas pour
les fonctions.

Arnaud

Avatar
Vincent Lascaux
Les spécialisations partielles sont autorisées pour les classes, pas pour
les fonctions.


D'accord...
Pourquoi de telles differences dans la norme entre les possibilités des
templates pour les classes et les fonctions ? (je pense aussi à la
résolution des templates inconnus qui est bien meilleure pour les fonctions
que pour les constructeurs de classe template il me semble).

--
Vincent

Avatar
Samuel Krempp
le Sunday 05 October 2003 23:49, écrivit :

Les spécialisations partielles sont autorisées pour les classes, pas pour
les fonctions.


D'accord...
Pourquoi de telles differences dans la norme entre les possibilités des
templates pour les classes et les fonctions ?


parcequ'il y a un mécanisme de résolution de surcharges des fonctions (y
compris templates), et personnellement je trouve ça déja assez compliqué
sans y ajouter d'éventuelle spécialisation partielle par dessus.
(j'imagine que ce serait possible, même si la mise en pratique des règles en
résultant pourrait être difficile pour un pauvre cerveau humain fatigué)

Du coté des templates de classes, il y a la spécialisation partielle,
Du coté des fonctions, la résolution de surcharge.
je crois que mélanger les 2 n'apporte pas grand chose d'autre que des
complications.

--
Sam


Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

[...]

| > Les fonctions template peuvent être spécialisées explicitement ; mais,
| > à l'inverse des classes templates, elles ne peuvent être spécialisées
| > partiellement.
|
| Est ce que tu peux préciser la difference entre ces deux spécialisations ?

D'abord, une spécialisation explicite est une vraie définition -- que
de ce soit de classe ou de template. Tout ce qu'il fait pour la
considérer, c'est que le compilateur se rende compte que les arguments
templates correspondent à cette définition là. C'est un élément
particulier de la famille désignée par le template primaire (ou général).

Une spécialisation reste toujours un template, i.e. ce n'est pas une
vraie classe. C'est une sous-famille de la famille désignée par le
template primaire. Il peut y en avoir plusieurs. Lorsqu'elles
existent, le compilateur doit les ordonner pour savoir lesquelles sont
plus spécialisées -- ce order n'est pas total. Et pour les ordonner,
on passe par le mécanisme de déduction d'argument template, mécanisme
défini pour les fonctions templates.

-- Gaby
Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| > Les spécialisations partielles sont autorisées pour les classes, pas pour
| > les fonctions.
|
| D'accord...
| Pourquoi de telles differences dans la norme entre les possibilités des
| templates pour les classes et les fonctions ?

Pour des raisons de simplicité ?

À la base -- i.e. sans template -- il y a déjà une différence
fondamentale entre une classe et une fonction : on peut surcharger une
fonction par une autre, mais on ne peut pas surcharger une classe par
une autre.

Ensuite, on peut techniquement imaginer la possibilité de la
spécialisation partielle des fonctions templates, mais cela ajouterait
une telle complexité que je ne suis pas certain que même toi tu
vourdrais du produit final.

| (je pense aussi à la
| résolution des templates inconnus qui est bien meilleure pour les fonctions
| que pour les constructeurs de classe template il me semble).

Là, je ne comprends pas ce que tu veux dire.

-- Gaby