2014-06-18 3 views
0

J'essaie de mettre en œuvre un simple gestionnaire de plugins en utilisant les concepts trouvés dans this answer. Je l'implémente en tant que modèle afin de pouvoir instancier différents gestionnaires pour les plugins implémentant différentes interfaces.Utilisation du paramètre de modèle comme argument dans un modèle

Cependant, je ne peux pas le compiler.

Voici un extrait qui illustre le problème:

#include <map> 
#include <string> 

template<typename InterfaceType> 
class PluginManager { 

public: 
    // Map between plugin name and factory function 
    typedef std::map<std::string, InterfaceType*(*)()> map_type; 

    static InterfaceType *createInstance(std::string const& plugInName) { 
     map_type::iterator iter = map().find(plugInName); 
     if (iter == map().end()) 
      return 0; 
     return iter->second(); 
    } 

protected: 
    static map_type & map() { 
     static map_type map; 
     return map; 
    } 

}; 

class MyInterface {}; 

PluginManager<MyInterface> myInterfacePluginManager; 

int main(int argc, char *argv[]) { 
} 

Lorsque vous essayez de le compiler, voici ce qui se passe:

$ g++ pimgr_bug.cpp 
pimgr_bug.cpp: In static member function ‘static InterfaceType* PluginManager<InterfaceType>::createInstance(const std::string&)’: 
pimgr_bug.cpp:12: error: expected ‘;’ before ‘iter’ 
pimgr_bug.cpp:13: error: ‘iter’ was not declared in this scope 
pimgr_bug.cpp:15: error: ‘iter’ was not declared in this scope 

Il semble être lié à la définition de map_type: si Je le modifie pour que le type de valeur de carte soit une classe concrète qu'il compile correctement, mais avec le type de valeur défini comme InterfaceType*(*)() ou tout autre élément lié à InterfaceType, alors cela ne fonctionne pas. La carte est supposée contenir une correspondance entre le nom du plugin et le pointeur vers une fonction d'usine correspondante. Il me manque presque certainement quelques notions de base de la syntaxe du template!

Est-il possible de créer une carte dans un modèle qui contient un type défini par l'un des arguments du modèle? J'utilise gcc 4.4.7 et malheureusement je ne peux pas utiliser C++ 11 (si c'est pertinent).

Merci!

+0

Essayez d'ajouter "typename", c'est-à-dire "typename map_type :: iterator". –

+0

gcc 4.8 donne un message d'erreur plus utile: * besoin de 'typename' avant' PluginManager :: map_type :: itérateur' car 'PluginManager :: map_type' est une portée dépendante * – Walter

+0

@MichaelAaronSafyan qui l'a corrigé. .. S'il ne s'agit pas d'un doublon, veuillez l'ajouter comme réponse – harmic

Répondre

0

map_type::iterator est un nom dépendant, car map_type dépend d'un paramètre de modèle (InterfaceType). Par la suite, le compilateur ne suppose pas que map_type::iterator attribue un nom à un type sauf si vous le dites explicitement *.

Par conséquent, écrire

typename map_type::iterator iter = map().find(plugInName); 

Et il devrait compiler très bien.

* ou la recherche de nom en trouve un, mais cela ne s'applique pas ici.

Questions connexes