template template

Le
Dimitri PAPADOPOULOS-ORFANOS
Bonjour,

Le code suivant compilait très bien jusqu'à des versions relativement
récentes de GCC (4.0.2 entre autres). J'avais d'ailleurs écrit ce code
après avoir consulté ce newsgroup.

#include <set>
using namespace std;

template <template <class U> class Container>
class MyClass {
Container<int> container;
};

int main() {
MyClass<set> instance;
}

Ça ne compile plus avec la version 4.2.2 de GCC.

J'ai bien essayé de changer de :
template <template <class U> class Container>
en :
template <template <typename> class Container>
mais sans succès.

Est-ce le code ou le compilateur qui pose problème ? Comment modifier le
code pour que ça marche ?

Merci d'avance,
--
Dimitri Papadopoulos
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fabien LE LEZ
Le #1066296
On Wed, 20 Feb 2008 18:48:44 +0100, Dimitri PAPADOPOULOS-ORFANOS :

Ça ne compile plus avec la version 4.2.2 de GCC.


Mais encore ? As-tu un message d'erreur ?

James Kanze
Le #1066295
On Feb 20, 6:48 pm, Dimitri PAPADOPOULOS-ORFANOS

Le code suivant compilait très bien jusqu'à des versions relativement
récentes de GCC (4.0.2 entre autres). J'avais d'ailleurs écrit ce code
après avoir consulté ce newsgroup.

#include <set>
using namespace std;

template <template <class U> class Container>


Note bien que ça ne permet la spécialisation qu'avec un template
à un seul paramètre. (Les collections de la norme en ont
toujours au moins deux, puisqu'il y a des allocateurs.)

class MyClass {
Container<int> container;
};

int main() {
MyClass<set> instance;
}

Ça ne compile plus avec la version 4.2.2 de GCC.


Ce qui m'étonne un peu, c'est que ça a compilé avant. Il devait
y avoir une extension qui prenait en compte les paramètres par
défaut.

J'ai bien essayé de changer de :
template <template <class U> class Container>
en :
template <template <typename> class Container>
mais sans succès.


Pour la plupart des collections de la norme :

template< template <class U, class A > class Container >
class MyClass
{
Container< int, std::allocator< int > > container ;
} ;

Pour set, il y a aussi le comparateur, donc :

template< template < class U, class C, class A > class Container >
class MyClass
{
Container< int, std::less< int >, std::allocator< int > >
container ;
} ;

(Et je ne crois pas qu'on peut surcharger les templates de
class.)

Est-ce le code ou le compilateur qui pose problème ? Comment
modifier le code pour que ça marche ?


C'est le code, mais je ne crois pas que tu es sorti de
l'auberge. Peut-être quelque chose avec des traits, ou de la
métaprogrammation. (On doit pouvoir différencier entre des
templates avec des fonctions du genre :
discriminator( ToTest< int >* = 0 ) ;
discriminator( ToTest< int, std::allocator< int > >* = 0 ) ;
discriminator( ToTest< int, std::less< int >, std::allocator< int
* = 0 ) ;
avec des types de rétour de tailles différentes, et une classe


de traits qu'on instancie selon la taile du type de rétour.)

--
James Kanze (GABI Software) email:
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


Anthony Fleury
Le #1066294
Bonjour,

Le code suivant compilait très bien jusqu'à des versions relativement
récentes de GCC (4.0.2 entre autres). J'avais d'ailleurs écrit ce code
après avoir consulté ce newsgroup.

#include <set>
using namespace std;

template <template <class U> class Container>
class MyClass {
Container<int> container;
};

int main() {
MyClass<set> instance;
}


Bonjour,

Ca n'aurait jamais dû compiler en fait.
Pour les template template parameters, il faut spécifier tous les
paramètres du template, donc pour std::set typiquement il faut spécifier
la fonction de comparaison et l'allocateur.

Pour corriger uniquement ce code-ci et le faire fonctionner :

#include <set>
using namespace std;

template <template <class T, class U, class V> class Container>
class MyClass {
Container<int, std::less<int>, std::allocator<int> > container;
};

int main() {
MyClass<set> instance;
}

Cela résoud le problème dans le cas unique de set, mais si MyClass est
instanciée avec un container ne prenant que 2 paramètres (vector, deque,
list), ca ne fonctionnera plus et je ne vois pas trop (comme ca sans
réflechir plus) comment résoudre ce problème...

Anthony

Dimitri PAPADOPOULOS-ORFANOS
Le #1089287
Bonjour,

Merci de vos conseils. Je pense qu'il va nous falloir enlever le
template et coder le type de container en dur. Une solution de de type
"traits" (si elle peut marcher) aurait pour nous le désavantage de :
1) perdre trop de temps à écrire le code,
2) en perdre 10 fois plus à le maintenir.

Le code suivant compilait très bien jusqu'à des versions relativement
récentes de GCC (4.0.2 entre autres). J'avais d'ailleurs écrit ce code
après avoir consulté ce newsgroup.

#include <set>
using namespace std;

template <template <class U> class Container>
class MyClass {
Container<int> container;
};

int main() {
MyClass<set> instance;
}

Ça ne compile plus avec la version 4.2.2 de GCC.


Pour info, le message d'erreur est :

template_template.cc: In function ‘int main()’:
template_template.cc:10: erreur:
type/value mismatch at argument 1 in template parameter list
for ‘template<template<class U> class Container> class MyClass’
template_template.cc:10: erreur:
expected a template of type ‘template<class U> class Container’, got
‘template<class _Key, class _Compare, class _Alloc> class std::set’
template_template.cc:10: erreur:
invalid type in declaration before ‘;’ token

Merci,
--
Dimitri Papadopoulos

Publicité
Poster une réponse
Anonyme