7 votes

C++ : spécifier une classe de base pour un paramètre de modèle

Je dois concevoir un cadre qui calcule le résultat d'un algorithme diviser-et-conquérir en parallèle. Pour utiliser ce cadre, l'utilisateur doit spécifier d'une manière ou d'une autre la procédure qui implémente la phase "divide" (une fonction de T à T), la phase "conquer" (une fonction de D à D) et T et D eux-mêmes.

J'ai pensé qu'il serait bien de définir deux classes abstraites, BaseDivide y BaseConquer qui déclare une méthode virtuelle pure compute avec les bons types : de cette façon, j'ai un type qui met en œuvre un concept bien défini (du point de vue du cadre) avec la fonction définissable par l'utilisateur incluse au moyen de la dérivation des classes abstraites.

J'ai pensé à utiliser des modèles pour transmettre les types au framework, afin que l'utilisateur n'ait pas à les instancier pour utiliser le framework, quelque chose comme ça :

template <typename T, typename D, typename Divide, typename Conquer> 
D compute(T arg);

Mon problème est que je veux que Diviser et Conquérir soient des types dérivés de BaseDivide y BaseConquer Il existe un moyen de le faire respecter au moment de la compilation. De plus : pensez-vous que je puisse obtenir un résultat similaire avec une conception plus propre ?

4voto

hirschhornsalz Points 16306

Vous pourriez créer les classes de base comme ceci :

struct BaseDivide {
    enum EnumDiv { derivedFromBaseDivide = true };
}

template <typename T, typename D, typename Divide, typename Conquer> 
    static_assert(D::derivedFromBaseDivide);
    D compute(T arg);

Quel est le but des paramètres supplémentaires du modèle Diviser et Conquérir ? Êtes-vous sûr d'en avoir besoin ?

2voto

Joel Falcou Points 3791

Utilisez Boost.EnabelIf pour déclencher SFINAE lorsque vos types ne répondent pas à vos exigences. Vérifier si T est dérivé de U se fait avec boost::is_base_of :

#include <boost/type_traits/is_base_of.hpp>
#include <boost/enable_if.hpp>

template <typename T, typename D, typename Divide, typename Conquer> 
typename boost::
enable_if_c< boost::is_base_of<BaseDivide,Divide>::value 
          && boost::is_base_of<BaseConquer,Conquer>::value
          ,D
          >::type
compute(T arg);

1voto

Scott Moonen Points 718

Vous n'avez pas besoin d'utiliser des modèles à cette fin. Au lieu de cela, vous pouvez utiliser des pointeurs vers les objets BaseDivide et BaseConquer, et le polymorphisme fera le travail pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X