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?

Était-ce utile?

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>());
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top