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

template template

4 réponses
Avatar
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

4 réponses

Avatar
Fabien LE LEZ
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 ?

Avatar
James Kanze
On Feb 20, 6:48 pm, Dimitri PAPADOPOULOS-ORFANOS
wrote:

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


Avatar
Anthony Fleury
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

Avatar
Dimitri PAPADOPOULOS-ORFANOS
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