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

Alias de template comme parametre de fonction template

7 réponses
Avatar
Aurélien REGAT-BARREL
Bonjour,
dans mon programme j'ai défini le type SmartPtr ainsi :

#include <boost/shared_ptr.hpp>

template<typename T>
struct SmartPtr
{
typedef boost::shared_ptr<T> Type ;
};

afin de pouvoir éventuellement changer de smart ptr plus tard.
Je défini mes types smart ptr ainsi :

typedef SmartPtr<int>::Type IntPtr;

Ok ça marche bien.
Problème : j'arrive pas à utiliser cet alias SmartPtr pour la détection
automatique des types dans les templates:

template<typename T>
void test( typename SmartPtr<T>::Type ptr )
{
*ptr = 10;
}

VC++ 7.1 n'est pas content :

'void test(SmartPtr<T>::Type)' : impossible de déduire l'argument de
modèle de 'T'

si je met boost::shared_ptr à la place ça marche :

template<typename T>
void test2( boost::shared_ptr<T> ptr )
{
*ptr = 10;
}

Mais j'aimerais bien faire pareil avec mon SmartPtr. Est-ce possible ?
Merci.


--
Aurélien REGAT-BARREL

7 réponses

Avatar
kanze
Aurélien REGAT-BARREL wrote:

dans mon programme j'ai défini le type SmartPtr ainsi :

#include <boost/shared_ptr.hpp>

template<typename T>
struct SmartPtr
{
typedef boost::shared_ptr<T> Type ;
};

afin de pouvoir éventuellement changer de smart ptr plus tard.
Je défini mes types smart ptr ainsi :

typedef SmartPtr<int>::Type IntPtr;

Ok ça marche bien.
Problème : j'arrive pas à utiliser cet alias SmartPtr pour la
détection automatique des types dans les templates:

template<typename T>
void test( typename SmartPtr<T>::Type ptr )
{
*ptr = 10;
}

VC++ 7.1 n'est pas content :

'void test(SmartPtr<T>::Type)' : impossible de déduire
l'argument de

modèle de 'T'


Le message d'erreur dit tout. C'est une contexte où la déduction
des types ne marche pas.

En fait, je vois mal comment un compilateur pourrait le faire.
Pour le compilateur, tu as passé un boost::shared_ptr<int>,
disons ; le typedef ne crée pas de nouveau type. Alors, comment
doit-il savoir quel type T utiliser pour que SmartPtr<T>::Type
soit boost::shared_ptr<int> ? Il faudrait en fait qu'il essaie
tous les types possibles, et il y en a une infinité.

si je met boost::shared_ptr à la place ça marche :

template<typename T>
void test2( boost::shared_ptr<T> ptr )
{
*ptr = 10;
}


Normal. Tu lui passe un boost::shared_ptr<X>. Si ce n'est pas
trivial, le compilateur arrive quand même à réconnaître que tu
lui a passé une instantiation du même template, et donc, de
savoir qu'il faut le même type.

Mais j'aimerais bien faire pareil avec mon SmartPtr. Est-ce
possible ?


Déplace le typedef à la portée d'un espace référentiel, et ça
doit marcher.

--
James Kanze GABI Software
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
Aurélien REGAT-BARREL
'void test(SmartPtr<T>::Type)' : impossible de déduire
l'argument de modèle de 'T'


Le message d'erreur dit tout. C'est une contexte où la déduction
des types ne marche pas.

En fait, je vois mal comment un compilateur pourrait le faire.
Pour le compilateur, tu as passé un boost::shared_ptr<int>,
disons ; le typedef ne crée pas de nouveau type. Alors, comment
doit-il savoir quel type T utiliser pour que SmartPtr<T>::Type
soit boost::shared_ptr<int> ? Il faudrait en fait qu'il essaie
tous les types possibles, et il y en a une infinité.


Hum je me doutais que c'était pas évident pour le compilo, mais j'avais pas
vu que c'était si complexe en effet (car ma struct est vide).
En fait c'est systématiquement le cas quand un paramètre template nécessite
un typename non ?

si je met boost::shared_ptr à la place ça marche :

template<typename T>
void test2( boost::shared_ptr<T> ptr )
{
*ptr = 10;
}


Normal. Tu lui passe un boost::shared_ptr<X>. Si ce n'est pas
trivial, le compilateur arrive quand même à réconnaître que tu
lui a passé une instantiation du même template, et donc, de
savoir qu'il faut le même type.

Mais j'aimerais bien faire pareil avec mon SmartPtr. Est-ce
possible ?


Déplace le typedef à la portée d'un espace référentiel, et ça
doit marcher.


Là par contre je pige pas.

--
Aurélien REGAT-BARREL


Avatar
James Kanze
Aurélien REGAT-BARREL wrote:
'void test(SmartPtr<T>::Type)' : impossible de déduire
l'argument de modèle de 'T'




Le message d'erreur dit tout. C'est une contexte où la
déduction des types ne marche pas.



En fait, je vois mal comment un compilateur pourrait le faire.
Pour le compilateur, tu as passé un boost::shared_ptr<int>,
disons ; le typedef ne crée pas de nouveau type. Alors,
comment doit-il savoir quel type T utiliser pour que
SmartPtr<T>::Type soit boost::shared_ptr<int> ? Il faudrait en
fait qu'il essaie



Hum je me doutais que c'était pas évident pour le compilo,
mais j'avais pas vu que c'était si complexe en effet (car ma
struct est vide). En fait c'est systématiquement le cas quand
un paramètre template nécessite un typename non ?


En gros, si tu as quelque chose du genre X::Y, il est impossible
au compilateur de deduire quoique ce soit de X, sans évaluer
tous les cas possible. Si X est un template, il y a une infinité
de cas possibles.

si je met boost::shared_ptr à la place ça marche :




template<typename T>
void test2( boost::shared_ptr<T> ptr )
{
*ptr = 10;
}




Normal. Tu lui passe un boost::shared_ptr<X>. Si ce n'est pas
trivial, le compilateur arrive quand même à réconnaître que tu
lui a passé une instantiation du même template, et donc, de
savoir qu'il faut le même type.



Mais j'aimerais bien faire pareil avec mon SmartPtr. Est-ce
possible ?




Déplace le typedef à la portée d'un espace référentiel, et ça
doit marcher.



Là par contre je pige pas.


Une erreur de ma part. Ce qu'il te faudrait, c'est un typedef
templaté. Ce qu'il n'y a pas (encore en tout cas) en C++.

La solution classique, c'est d'écrire ta propre classe SmartPtr,
en se servant de boost::shared_ptr au niveau de
l'implémentation. Même si c'est un peu plus de boulot.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34



Avatar
Aurelien REGAT-BARREL
Une erreur de ma part. Ce qu'il te faudrait, c'est un typedef
templaté. Ce qu'il n'y a pas (encore en tout cas) en C++.


Ok merci.
Une dernière question : ça a été proposé pour le prochain standard (C++0x)
si j'ai bien compris. Mais quand est-ce qu'il est prévu ce prochain standard
?

--
Aurélien REGAT-BARREL

Avatar
James Kanze
Aurelien REGAT-BARREL wrote:
Une dernière question : ça a été proposé pour le prochain
standard (C++0x) si j'ai bien compris. Mais quand est-ce qu'il
est prévu ce prochain standard ?


Je ne sais pas. À vrai dire, ça me semble un peu prématuré,
étant donné la rarité des compilateurs qui supportent la norme
actuelle.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
Aurélien REGAT-BARREL
Je ne sais pas. À vrai dire, ça me semble un peu prématuré,
étant donné la rarité des compilateurs qui supportent la norme
actuelle.


C'était pour avoir une idée de l'odre d'ici 2 ans / 10 ans. Mais bon si j'ai
bien compris rien n'est planifié.
"la rareté des compilateurs qui supportent la norme actuelle" : il y en a
qui supportent la norme à 100% ?

--
Aurélien REGAT-BARREL

Avatar
James Kanze
Aurélien REGAT-BARREL wrote:
Je ne sais pas. À vrai dire, ça me semble un peu prématuré,
étant donné la rarité des compilateurs qui supportent la norme
actuelle.



C'était pour avoir une idée de l'odre d'ici 2 ans / 10 ans.
Mais bon si j'ai bien compris rien n'est planifié.


"la rareté des compilateurs qui supportent la norme actuelle" : il y en a
qui supportent la norme à 100% ?


Oui et non. Le langage C++ (comme prèsque tout langage de
programmation) est assez complexe que s'attendre à un
compilateur sans la moindre erreur n'est pas raisonable, et les
erreurs feront en général que le compilateur n'est pas 100%
conforme. Abstraction faite des erreurs potentielles, le
front-end de EDG a des modes où il est 100% conforme ; autant
que je sache, il y a au moins deux compilateurs (Comeau et
Intel) qui sont livrés avec tout ce qu'il faut activé pour être
conforme.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34