voici le mot clef typename, que trop peu connaissent.
typename A
permet de spécifier au compilateur que A est un type (ce qui n'est pas toujours évident)
2 utilisations:
* en remplacement dans les paramètre de types dans les déclaration des templates
Code :
- template <class T> Foo;
|
peut s'ecrire avec préférence
Code :
- template <typename T> Foo;
|
retenez-le, histoire de ne pas être surpris
* pour permettre au compilateur certaines résolutions de type. ceci concerne les templates: vous avez une classe template<typename T> et dans cette classe, vous souhaitez manipuler un sous-type (pas au sens de l'héritage, je retrouve pas le mot) de T, T::sous_type. Très bien, mais ça ne passera pas à la compilation, votre compilateur va perdre les pedales: il ne connait même pas T !!!
alors à vous de lui spécifer que T::sous_type est bien un type.
pour des raisons historiques, class est trop souvent utilisé, et pose souvent problème aux débutants puisque class à déjà un autre emploi (est ce que ça va marcher avec mes struct, mes int ??)
typename porte bien son nom, utilisez le.
petit exemples à tester
Code :
- template<typename T>
- class Foo
- {
- public:
- typedef T data_type;
-
- typedef typename data_type::data_type nestded_data_type;
- void go() const
- {
- nestded_data_type i;
- // si vous n'avez pas fait de typedef
- typename T::data_type j;
- i = j;
- }
- };
- class Bar
- {
- public:
- typedef int data_type;
- };
- class Baz
- {
- public:
- typedef float data_type;
- };
- #include <iostream>
- #include <typeinfo>
- using namespace std;
- int main()
- {
- Foo<Bar>::nestded_data_type a;
- Foo<Baz>::nestded_data_type b;
- cout << typeid(a).name() << endl
- << typeid(b).name() << endl;
- Foo<Bar> r;
- Foo<Baz> z;
- r.go();
- z.go();
- }
|
autre exemple
Code :
- #include <iostream>
- using std::cout;
- using std::endl;
- struct Rose {};
- struct A { typedef Rose rose; };
- template<typename T>
- struct B : T { typedef typename T::rose foo; };
- template<typename T>
- void smell( T ) { cout << "awful" << endl; }
- void smell( Rose ) { cout << "sweet" << endl; }
- int main() {
- smell( A::rose() );
- smell( B<A>::foo() );
- }
|
Message édité par Taz le 19-04-2004 à 23:14:47