Mixins, modèles variadique et CRTP en C ++
Question
Voici le scénario: Je voudrais avoir une classe d'accueil qui peut avoir un nombre variable de mixins (pas trop dur avec des modèles variadique - voir par exemple http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.144 ). Cependant, je voudrais aussi mixins à être paramétrés par la classe d'accueil, afin qu'ils puissent se référer à ses types publics (en utilisant l'idiome CRTP). Le problème se pose en essayant de mélanger les deux - la syntaxe correcte est pas clair pour moi. Par exemple, le code suivant ne peut pas compiler avec g ++ 4.4.1:
template <template<class> class... Mixins>
class Host : public Mixins<Host<Mixins>>... {
public:
template <class... Args>
Host(Args&&... args) : Mixins<Host>(std::forward<Args>(args))... {}
};
template <class Host> struct Mix1 {};
template <class Host> struct Mix2 {};
typedef Host<Mix1, Mix2> TopHost;
TopHost *th = new TopHost(Mix1<TopHost>(), Mix2<TopHost>());
Avec l'erreur:
tst.cpp: In constructor ‘Host<Mixins>::Host(Args&& ...) [with Args = Mix1<Host<Mix1, Mix2> >, Mix2<Host<Mix1, Mix2> >, Mixins = Mix1, Mix2]’:
tst.cpp:33: instantiated from here
tst.cpp:18: error: type ‘Mix1<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’
tst.cpp:18: error: type ‘Mix2<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’
Quelqu'un at-il une expérience réussie mélange des modèles variadique avec CRTP?
La solution
Ce qui suit semble fonctionner. J'ai ajouté Mixins...
dans les classes mixins héritées qui élargit le pack de paramètres enplace. En dehors du corps du modèle de Host
, tous les paramètres du modèle de Host
doit être spécifié si Mixins...
sert le but. A l'intérieur du corps, juste Host
suffit pas nécessaire de préciser tous les paramètres du modèle. Type d'une main courte.
#include <utility>
template <template<class> class... Mixins>
class Host : public Mixins<Host<Mixins...>>...
{
public:
Host(Mixins<Host>&&... args) : Mixins<Host>(std::forward<Mixins<Host>>(args))... {}
};
template <class Host> struct Mix1 {};
template <class Host> struct Mix2 {};
int main (void)
{
typedef Host<Mix1, Mix2> TopHost;
delete new TopHost(Mix1<TopHost>(), Mix2<TopHost>());
}