2012-02-02 1 views
2

J'essaie de créer une classe modèle qui contient une liste statique d'objets dont il n'existe qu'un seul. Ce que j'ai jusqu'ici fonctionne mais il me donne une copie de "mylist" pour chaque type différent de paramètre de classe B. Comment puis-je le changer pour avoir un "mylist" pour toutes les instanciations de classe B sans tenir compte des paramètres du template?Utilisation de variables statiques avec des modèles

C'est ce que j'ai:

template <class T> class A { 
    ... 
}; 
template <class T> class B { 
    static list<A<T> > mylist; 
    ... 
}; 
template <class T> list< A<T> > B<T>::mylist; 

Merci à l'avance :)

+7

Vous êtes fondamentalement en train de mal interpréter les modèles. Étant donné 'template class Foo;', chaque instance de 'Foo ' pour différents 'T's est un type _ complètement différent. Par conséquent, si 'Foo <>' contient un membre de données statiques, chaque instance de 'Foo ' pour différents 'T' contiendra un membre de données statiques différent. Pour avoir un membre de données qui peut contenir différents types, regardez [Boost.Variant] (http://www.boost.org/libs/variant/) si tous les types sont connus à l'avance, ou [Boost.Any] (http: //www.boost.org/libs/any/) sinon. (Mais vraiment, votre conception semble très discutable en premier lieu.) – ildjarn

+0

Êtes-vous après un singleton? http://www.infernodevelopment.com/singleton-c – Joel

Répondre

4

Comment changer de sorte que je n'ai qu'une copie

Vous pouvez hériter d'un classe de base commune (non-template) pour s'assurer qu'il n'y a pas d'instance pour chaque instanciation de template.

... qui contient tout type?

Cela dépend de vos attentes. Je vais supposer de votre exemple que "n'importe quel type" signifie "n'importe quelle instanciation de la classe de modèle A".

Étant donné que ces types peuvent varier en taille, vous ferez mieux avec des pointeurs de maintien sur les objets.

Ceci est un exemple d'une solution qui résoudrait ces deux problèmes.

class ACommon { 
    // Put a common virtual interface here. 
}; 

template <class T> class A : public ACommon { 
}; 

class BCommon { 
    // You'll have a single, common static here. 

    static list<shared_ptr<ACommon> > mylist; 
}; 

template <class T> class B : public BCommon{ 

}; 
1

Vous ne pouvez pas "juste" avoir un type dans une liste, vivant côte à côte. En fonction de ce que vous attendez de cette liste et des objets qu'elle contient, il y a plusieurs choses à faire.

Une alternative à la solution de Drew serait: Vous avez absolument besoin de BCommon si vous voulez une seule liste pour toutes les instanciations. Si vous ne voulez pas cacher vos types A derrière une interface, vous pouvez utiliser Boost :: any ou Boost :: variant pour contenir vos objets A.

+0

Oui, 'boost :: any' et' boost :: variant' seraient de bons cas d'utilisation ici. Agréable. –

+0

'boost :: variant 'est un peu dangereux de la part d'un novice; puisque c'est une union, elle prend la taille du plus grand type. Un novice, sans s'en rendre compte, pourrait perdre beaucoup de mémoire, juste pour stocker un gros objet à côté d'un million d'euros. 'boost :: any 'est une histoire différente. Bien que cela ne provoque pas de comportement indéfini en raison d'un mauvais cast (comme un void *), il pourrait faire planter votre programme "sur le terrain" en raison d'une'bad_cast_exception 'non gérée. À mon humble avis, pour% 90 des cas, votre solution est la voie à suivre. – enobayram

Questions connexes