2010-05-25 4 views
7

J'ai une usine de classe où j'utilise des modèles variadiques pour les paramètres c'tor (code ci-dessous). Cependant, lorsque j'essaie de l'utiliser, j'obtiens des erreurs de compilation; quand je l'ai écrit à l'origine sans paramètres, cela a bien fonctionné.Usine de classe C++ 0x avec problème de modèles variés

Voici la classe:

template< class Base, typename KeyType, class... Args > 
class GenericFactory 
{ 
public: 
    GenericFactory(const GenericFactory&) = delete; 
    GenericFactory &operator=(const GenericFactory&) = delete; 

    typedef Base* (*FactFunType)(Args...); 

    template <class Derived> 
    static void Register(const KeyType &key, FactFunType fn) 
    { 
     FnList[key] = fn; 
    } 

    static Base* Create(const KeyType &key, Args... args) 
    { 
     auto iter = FnList.find(key); 
     if (iter == FnList.end()) 
     return 0; 
     else 
     return (iter->second)(args...); 
    } 

    static GenericFactory &Instance() { static GenericFactory gf; return gf; } 
private: 
    GenericFactory() = default; 

    typedef std::unordered_map<KeyType, FactFunType> FnMap; 
    static FnMap FnList; 
}; 

template <class B, class D, typename KeyType, class... Args> 
class RegisterClass 
{ 
public: 
    RegisterClass(const KeyType &key) 
    { 
     GenericFactory<B, KeyType, Args...>::Instance().Register(key, FactFn); 
    } 
    static B *FactFn(Args... args) 
    { 
     return new D(args...); 
    } 
}; 

Voici l'erreur: lors de l'appel (par exemple)

// Tucked out of the way 
RegisterClass<DataMap, PDColumnMap, int, void *> RC_CT_PD(0); 

GCC 4.5.0 me donne:

In constructor 'RegisterClass<B, D, KeyType, Args>::RegisterClass(const KeyType&) [with B = DataMap, D = PDColumnMap, KeyType = int, Args = {void*}]': 
no matching function for call to 'GenericFactory<DataMap, int, void*>::Register(const int&, DataMap* (&)(void*))' 

je peux » Je ne vois pas pourquoi il ne sera pas compilé et après une recherche approfondie, je n'ai pas trouvé la réponse. Quelqu'un peut-il me dire ce que je fais mal (en dehors de l'étrange nom de la variable, qui a un sens dans le contexte)?

+0

En quoi ces classes sont-elles utiles? Pouvez-vous donner un exemple simple de la façon dont ils seraient utilisés si cela était compilé? –

+0

C'est pour quand vous avez besoin d'instancier une classe dérivée mais vous ne savez que la classe dont vous avez besoin à l'exécution. Le paramètre 'Args' est pour quand le constructeur de classe a des arguments. – user350096

+0

Dans le code inclus dans la question 'GenericFactory' n'est même pas une classe modèle. Je suppose que vous devriez le réparer pour obtenir de l'aide. – doublep

Répondre

2

Je pense qu'il est barfing ici:

template <class Derived> 
static void Register(const KeyType &key, FactFunType fn) 
{ 
    FnList[key] = fn; 
} 

Vous n'utilisez pas Derived dans cette fonction, mais il est probablement gâcher la tentative de gcc pour résoudre GenericFactory<...>.Register(...). Vous pouvez également changer cela en GenericFactory<...>::Register(...).

+0

Merci, cela a fonctionné. Je savais que ça devait être quelque chose de simple! – user350096

Questions connexes