Le code suivant représente un conteneur basé sur std :: vecteur est-il possible de templatiser std :: Vector et de créer un conteneur général, quelque chose comme ça? P> < Pré> xxx pré> où stl_container représente std :: vecteur, std :: liste, std :: set ...? Je voudrais choisir le type de conteneur au moment de la création. p> merci pour vos réponses ... p> Question mise à jour: strong> p> J'ai essayé ce qui suit code mais il y a des erreurs: p>
6 Réponses :
oui et non.
Vous pouvez utiliser un paramètre de modèle de modèle, par exemple P> Toutefois, en général, les paramètres de modèle de modèle ne sont pas particulièrement utiles car le nombre et les types de paramètres de modèle doivent correspondre. Donc, ce qui précède ne correspondrait pas Pour pouvoir utiliser le modèle Cependant, avec ce modèle, vous ne pourriez pas utiliser le Habituellement, il est beaucoup plus facile d'éviter les paramètres de modèle de modèle à cause de cette inflexibilité. p> p> std :: vecteur code> car il dispose de deux paramètres de modèle: une pour le type de valeur et une pour l'allocator. Un paramètre modèle de modèle ne peut pas tirer parti des arguments de modèle par défaut. P>
std :: vecteur code> comme argument,
TLIST Code> devrait être déclaré comme: p>
std :: map code> Modèle comme argument car il a quatre em> paramètres de modèle: Types de la clé et de la valeur, du type d'allocator et du type de comparateur. P>
Pourriez-vous remplacer Modèle
Typename conteneur code> et accédez au type contenu dans le conteneur à l'aide de
conteneur :: valeur_type code> ?
@Billy: Bien sûr; Chaque conteneur a un valeur_type code> Typef. Cependant, cela ne vous permettra pas de créer i> le conteneur, qui est ce que l'OP est question.
@James: ah - je vois. On dirait que l'OP a besoin de certains itérateurs alors :)
Bien sûr, il suffit de regarder ce que STD :: Stack fait!
@Bo: Eh bien, std :: pile code> ne prend pas de modèle, il faut un type de conteneur. C'est-à-dire qu'il ne faut pas
std :: deque code>, il faut
std :: deque
Étant donné que le vecteur et la carte sont résolument différents types de conteneurs, qui partagent très peu d'une portée d'utilisation, le problème que vous mentionner me semble être un problème pratique.
@Crazy: Eh bien, j'ai choisi std :: map code> car il est apparu dans la liste de l'OP et dispose d'une liste de paramètres de modèle qui ne correspond pas au paramètre
std :: vecteur code> liste. C'est toujours un problème, même pour les conteneurs de séquence: tandis que tous les conteneurs de séquence de bibliothèque standard (à l'exception du tableau
TRAY code> in c ++ 0x) ont deux paramètres de modèle de type (
t code> et
alloc code>), il n'est pas nécessaire que d'autres conteneurs définis par l'utilisateur ont exactement deux paramètres de modèle de type; Un conteneur défini par l'utilisateur peut avoir des paramètres de modèle plus ou moins ou différents.
@Crazy: Puissons std :: Set Code> Ensuite, non associatif, et encore 3 paramètres au lieu du 2 de
std :: vecteur code>.
@Matthieu M. M. - J'espère que vous ne pensez pas que ces deux conteneurs sont interchangeables.
est-il possible de templatiser std :: Vector et de créer un conteneur général, quelque chose comme ça? P>
non. Vous devriez templatiser la fonction ou l'objet en utilisant em> le conteneur - vous ne pouviez pas templatiser le conteneur lui-même. P>
Par exemple. Considérons un
std :: Recherche code>: p>
xxx pré> Ceci fonctionne pour n'importe quel conteneur, mais n'a pas besoin d'une tempalte avec le conteneur du tout. < / p>
Également, étant donné qu'il ressemble à ce que vous essayez de faire est de faire du code indépendant du conteneur, vous voudrez peut-être vous acheter ou emprunter une copie de Scott Meyers ' efficace STL em> et lisez l'élément 2: Méfiez-vous de l'illusion du code indépendant du conteneur. P> blockQuote>
Les algorithmes n'entraînent-ils que des itérateurs, plutôt que des conteneurs / gammes partiellement la cause de l'impossibilité du code indépendant du conteneur? IT est I> possible d'écrire une fonction de recherche générique, qui fonctionne également efficacement pour la définition et la carte, mais pas avec cette signature.
@Unclebens: Oui - L'article de STL efficace décourage à ne pas essayer d'utiliser uniquement des fonctionnalités que tous les conteneurs STL fournissent, de sorte qu'ils puissent les éteindre. (Meyers est préférable à expliquer que moi) si vous pouvez templatiser un algorithme au moyen d'un modèle, alors par tous les moyens. (Mais vous aurez probablement besoin de quelques spécialisations de modèles si vous voulez que ce soit le plus efficace pour les conteneurs séquentielles et associatifs;))
En ce qui concerne l'élément 2: méfiez-vous l'illusion du code indépendant du conteneur, n'est-ce pas la plupart des algorithmes de STL sous cet esprit?
@Kirakun: Les algorithmes sont mis en œuvre en termes d'itérateurs et non de conteneurs.
Eh bien, vous pouvez le pirater avec une macro:
template <typename T, typename stl_container = std::vector<T> > struct TList { typedef stl_container Type; }; #define TLIST(T, C) TList<T, C<T> > TList<int> foo; TList<int, std::list<int> > bar; TLIST(int, std::list) baz;
Cuz je suis un amoureux de chat ;-). Mais oui, c'est un hack.
Oui, mais pas directement: alors vous pouvez définir différentes stratégies de conteneur: p> un peu verbeuse, cependant. * Faire des choses directement, vous auriez besoin de prendre L'itinéraire décrit par James , mais Comme il le note, cela est finalement très inflexible. P> Cependant, avec C ++ 0x, nous pouvons le faire tout simplement bien: P> template <typename T, typename Container>
struct rebind; // not defined
template <typename T, typename Container, typename... Args>
struct rebind<T, Container<Args...>>
{
// assumes the rest are filled with defaults**
typedef Container<T> type;
};
Bonne idée. Y a-t-il un problème qui ne peut-il pas être résolu avec une couche supplémentaire d'indirection?
@James: Nope. Je peux même voir mon front si j'utilise un miroir.
Lol - c'est soigné. Et les commentaires sont hilarants. +1.
Pour la ligne TypeDef Typename Conteneur
@ROBO: Je n'ai pas cette ligne. (Vous avez :: Type code> pendant que j'ai
:: Type code>.) Dans tous les cas, quel code êtes-vous compilé?
@Gman> J'ai placé votre code dans ma question, voir ci-dessus, s'il vous plaît. Je pensais :: Type était une surveillance ...
@ROBO: Oh oui, désolé, faute de frappe dans ma réponse. Fixé. (Notez votre code posté dans la question omits mapp_container code>, cependant.) (Et @dowvoter: Commentaire? Impossible de réparer les choses si je ne sais pas ce qui ne va pas.)
@Gman. Merci de votre réponse ... J'ai somnolent et je n'ai pas remarqué votre dernier commentaire :-) La première option est suffisante ... demain je vais essayer (éventuellement) revenir.
Et avec des alias de modèle, vous pouvez écrire modèle
Je ne suis pas suivant comment vous allez sur les choses dans le bloc de code suivant les mots "Cependant, avec C ++ 0x, nous pouvons le faire juste bien:". Le moyen évident de faire est d'utiliser des modèles TypeDef. Cela ne ressemble pas à ce que vous faites, cependant. La fonctionnalité que vous pouvez ajouter des arguments de modèle de trailing arbitariat en C ++ 0x? Si oui, pouvez-vous ajouter une référence, s'il vous plaît? Merci.
Ah, je vois. Vous utilisez Modèles VARIADIC ici, non? Donc, cela peut être résolu par l'un ou l'autre modèle TypeDefs ou les modèles variadiques, on dirait. Qui sont des opérations complémentaires, d'une certaine manière. On vous permet de réduire le nombre de modèles, l'autre vous permet de les prolonger. :-)
Je suis un peu perplexe Pourquoi des personnes très intelligentes (et compétentes) disent non.
sauf si j'ai mal interprété votre question, ce que vous essayez d'accomplir est pratiquement identique aux "adaptateurs de conteneurs" dans la bibliothèque standard. Chacune fournit une interface à certains types de conteneurs sous-jacents, le type de conteneur qui sera utilisé fourni sous forme de paramètre de modèle (avec une valeur par défaut). P>
Par exemple, un Bien sûr, je n'ai peut-être pas mal compris la question - si oui, je m'excuse d'avance aux personnes avec qui je 'm (sorte de) désaccord. p> p> std :: pile code> utilise un autre conteneur (par exemple,
std :: deque code>,
std :: Liste code> ou
std :: vecteur code>) pour maintenir les objets, et
std :: pile code> lui-même fournit simplement une interface simplifiée / restreinte lorsque vous souhaitez simplement utiliser des opérations de pile. Le conteneur sous-jacent qui sera utilisé par le
std :: pile code> est fourni sous forme de paramètre de modèle. Voici comment le code regarde dans la norme: p>
Jerry: le code OP veut écrire comme myClass
std :: vecteur
STD :: Stack CODE> EXEMPLE, le numéro de code transduit n'est pas
std :: deque code>, c'est
std :: deque
myClass
@Billy O'Neal: J'ai relu la question et je ne trouve toujours pas où il dit que c'est ce qu'il veut. Peut-être que je n'ai tout simplement pas suffisamment de sommeil la nuit dernière ou quelque chose que ....
Je pense que le point de la question était d'obtenir le conteneur sans passer de type entier dans le paramètre de modèle. (Par exemple, je peux donc faire le type de valeur secret_type
@Jerry: Voir la deuxième boîte de Code de l'OP. (Regarde le typlef là-bas)
@Gman: C'est peut-être ce qu'il veut, mais je ne trouve rien dans la question qui semble le dire. Mon impression était simplement qu'il voulait quelque chose comme un adaptateur de conteneur, lui permettant de brancher un conteneur sous-jacent différent lorsque / s'il voit en forme.
@Billy O'Neal: Je l'ai regardé. Je ne peux pas voir où il fait beaucoup pour soutenir votre position cependant.
@Jerry: Afin de compiler, le typename stl_container code> devrait être un modèle de modèle (comme dans @james ') répondre.
J'ai lu la question de la même manière @gman. Il est tout à fait possible que je lis ça faux, cependant. Cette solution est, imo, la solution la plus naturelle.
@Billy O'Neal: Mais même s'il s'agissait d'un modèle de modèle, cela ne compilerait toujours pas. Un typlef doit ressembler à quelque chose comme typedef Somenye somename; Code> Ce qu'il a est (au mieux) juste
Typefef-sentatype; code>, sans nom pour le typeDEF. Je pense que beaucoup trop de travail est en train de mettre en place une syntaxe très spécifique, quand tout ce qu'il semble (à moi) est à faire, c'est essayer de représenter l'idée générale que l'intérieur de sa classe, le type de conteneur sous-jacent sera transmis comme paramètre.
@James McNellis: Eh bien, je suppose qu'à ce stade, peu importe beaucoup. Il a maintenant des réponses qui couvrent à la fois des possibilités (et que c'est ce que la réponse de l'OP ou non, la réponse de Gman est assez cool).
Vous pouvez utiliser des paramètres de modèle de modèle, car d'autres ont mentionné ici. La principale difficulté avec ceci n'est pas que les types de conteneurs dissemblables ont des paramètres de modèle différents, mais que la norme permet aux conteneurs standard, comme le vecteur, de disposer de paramètres de modèle en plus des paramètres documentés, nécessaires.
Vous pouvez déplacer cela par Fournir à vos propres types de sous-classe qui acceptent les paramètres de modèle appropriés et que tous les extras (qui doivent avoir des paramètres par défaut) sont remplis dans ma mise en œuvre: p> ou vous pouvez utiliser le modèle Typedef idiom: p>
Je doute parce que vous héritez de conteneurs standard. Ils n'ont pas de destructeur virtuel, il est donc dangereux d'utiliser votre classe simple_vector
vecteur
vecteur
simple_vector
Pas dans ce cas Alexandre. Donnez-vous un moment ou deux pour y penser. Ou plus longtemps ...
Qui utiliserait cette classe? Pourquoi ne peut pas
list code> il suffit d'utiliser
typéfef vecteur / liste / définir <élément> éléments code>? Quel serait le but d'une classe qui, étant donné un type de conteneur et un type de valeur, met simplement ces deux ensemble?
Re: Le Modifier, je ne vois toujours pas pourquoi vous ne pouvez pas écrire
list> liste; code> etc.