2009-06-02 8 views
4

Soyez prévenus: Cette question semble beaucoup plus évidente qu'elle ne l'est en réalité.Comment écrire un modèle C++ qui accepte tous les modèles de classe et de classe?

Je voudrais écrire un modèle qui peut accepter n'importe quelle classe concrète ou classe de modèle en tant que paramètre de modèle. Cela peut sembler inutile car sans savoir si le passé en T est modélisé ou non, vous ne saurez pas comment l'utiliser. La raison pour laquelle je veux ceci est que je peux déclarer un modèle général sans définition, que les utilisateurs se spécialisent ensuite. Parce que les utilisateurs le spécialisent, ils connaissent toujours le type auquel ils ont affaire. Mais les utilisateurs ne peuvent pas spécialiser un modèle sans le déclarer d'abord.

Vous pouvez le faire:

template<class T> 
class myclass; 

Mais cela ne fonctionnera pas si vous passez dans un T basé sur un modèle, par exemple myclass<std::vector> ne fonctionnera pas. Donc, nous essayons ceci:

template<class T> 
class myclass; 

template<template<class> T> 
class myclass; 

Cela pourrait être la bonne voie, mais il ne fonctionne pas comme cela est parce que les modèles de classe ne peuvent pas être surchargées. Alors, passons à des modèles de fonction, qui peuvent être:

template<class T> 
void myfunc(); 

template<template<class> T> 
void myfunc(); 

Doux, alors nous avons terminé? Eh bien, il peut y avoir différents nombres de paramètres donnés au paramètre du modèle de modèle, nous devons donc en tenir compte également.

template<class T> 
void myfunc(); 

template<template<class> T> 
void myfunc(); 

template<template<class, class> T> 
void myfunc(); 

template<template<class, class, class> T> 
void myfunc(); 

// etc. 

laid, mais le Boost Preprocessor Library peut générer ce code pour nous (et en C++ 0x d'avoir des modèles variadique sera ajouté si cette laideur est temporaire). Mais nous avons encore oublié un cas! Que faire si l'un des paramètres de T n'est pas une classe, mais un entier constant. Essayons de soutenir cela:

template<class T> 
void myfunc(); 

template<template<class> T> 
void myfunc(); 

template<template<class, class> T> 
void myfunc(); 

template<template<class, class, class> T> 
void myfunc(); 

// etc. 

template<template<class> T> 
void myfunc(); 

template<template<class, int> T> 
void myfunc(); 

template<template<int, class> T> 
void myfunc(); 

template<template<int, class, class> T> 
void myfunc(); 

template<template<class, int, class> T> 
void myfunc(); 

template<template<class, class, int> T> 
void myfunc(); 

// etc. 

Uh oh. Étant donné que tout type constant peut être passé dans un modèle, dans n'importe quel nombre, mélangé avec des paramètres de classe, explosion combinatoire KABLOOEY. Juste pour rendre les choses plus difficiles, que se passe-t-il si les paramètres de T sont eux-mêmes des modèles?

+5

Je voudrais revenir à la planche à dessin et définir clairement les exigences. Que veux-tu accomplir? Cela a-t-il du sens de mélanger des modèles et des classes (notez que std :: vector est une classe, pas un modèle). Qu'est-ce que vous essayez vraiment de résoudre? –

Répondre

3

boost :: mpl fait quelque chose comme ça (voici leur idée de binding an argument).Cependant, vous devez faire beaucoup d'hypothèses pour le faire fonctionner, comme l'utilisation;

template <class T> foo { }; typedef foo< int_<4> > my_foo_4; 

au lieu de

template <int T> foo { }; typedef foo<4> my_foo_4; 

ne pas avoir à offrir pour tous les surcharges int, char, bool, etc combinaison.

Je ne peux pas penser à quelque chose qui serait plus efficace que l'approche boost :: mpl, et en général, je pense que toute approche souffrirait de beaucoup de problèmes; un template de classe n'est PAS un type, et il ne peut pas vraiment être coincé dans le système de type (boost :: mpl le traite comme une fonction pour créer de nouveaux types, plus génériquement, il est utilisé pour créer une "MetaFunction") . Je ne suis même pas sûr que les modèles variés vont affecter les paramètres du modèle de template (question intéressante cependant).

+1

Todd, ils le feront. en C++ 1x, vous serez en mesure de faire le modèle struct Take; template