   Storing templated function pointers
  I'm working on a factory class, and basically when you register a new type it stores a templated function that creates an instance of that type.  It's given me errors though.  I'm wondering if you can do this?The code is rather short so I'll just post it instead of confusing you all with my awful explanation ability./* --------------------------------------------------------------File:AXScene.hDescription:This file defines an class that manages a scene.Date:December 19, 2005Author:James-------------------------------------------------------------- */#if !defined(AXSCENE_INCLUDED)#define AXSCENE_INCLUDEDclass AXScene {public:AXScene();virtual ~AXScene();template<class Type>void RegisterEntityType(string Name) {EntityRegistrar.insert(Name, &(EntityCreator<Type>));}shared_ptr<AXEntity> CreateEntity(string Type, string Name, string Parameters) {map<string, EntityCreatorPtr >::iterator Iter = EntityRegistrar.find(Type);if(Iter != EntityRegistrar.end()) return ((*Iter).second)(Name, Parameters);else return shared_ptr<AXEntity>();}shared_ptr<AXEntity> GetEntity(string Name) {map<string, shared_ptr<AXEntity> >::iterator Iter = EntityMap.find(Name);if(Iter != EntityMap.end()) return (*Iter).second;else return shared_ptr<AXEntity>();}AXSceneNode* GetRootSceneNode() {return &RootSceneNode;}private:typedef shared_ptr<AXEntity> (*EntityCreatorPtr)(string, string);template<class Type>shared_ptr<AXEntity> EntityCreator(string Name, string Parameters) {shared_ptr<Type> Entity(new Type(Name, Parameters));EntityMap.insert(Name, Parameters);return Entity;}AXSceneNode RootSceneNode;map<string, shared_ptr<AXEntity> > EntityMap;map<string, EntityCreatorPtr> EntityRegistrar;};#endifIt's pretty obvious that the problem is I'm storing a type EntityCreatorPtr which has the same function declaration as EntityCreator without the template.  And then I try to add something like "&(EntityCreator<Type>)".   How can I store the generated function that creates an instance of a specific type?  What kind of function declaration to I typedef as EntityCreatorPtr?I could solve this by using a templated class instead of a templated function, but I'm curious if you can even do this now.   
  As far as I can tell you have two problems (and one point of really bad style). Problem one is that your call to std::map<>::insert() is incorrect in every place you use it. insert() takes a std::pair<key, value>, not two arguments. The second problem is that you're trying to assign a pointer to a member function to a regular function pointer. This is non-kosher. The bad point of style is that you seem to have a using namespace somewhere in your header file chain. Blech.I got your code to compile with a few changes:class AXScene {public:  AXScene() {}  virtual ~AXScene() {}template<class Type>void RegisterEntityType(string Name) {    EntityRegistrar.insert( make_pair(Name, &AXScene::EntityCreator<Type> ) );}shared_ptr<AXEntity> CreateEntity(string Type, string Name, string Parameters) {map<string, EntityCreatorPtr >::iterator Iter = EntityRegistrar.find(Type);if(Iter != EntityRegistrar.end()) return (this->*(Iter->second))(Name, Parameters);else return shared_ptr<AXEntity>();}shared_ptr<AXEntity> GetEntity(string Name) {map<string, shared_ptr<AXEntity> >::iterator Iter = EntityMap.find(Name);if(Iter != EntityMap.end()) return (*Iter).second;else return shared_ptr<AXEntity>();}AXSceneNode* GetRootSceneNode() {return &RootSceneNode;}private:  typedef shared_ptr<AXEntity> (AXScene::*EntityCreatorPtr)(string, string);template<class Type>shared_ptr<AXEntity> EntityCreator(string Name, string Parameters) {shared_ptr<Type> Entity(new Type(Name, Parameters));EntityMap.insert( make_pair(Name, Entity) );return Entity;}AXSceneNode RootSceneNode;map<string, shared_ptr<AXEntity> > EntityMap;map<string, EntityCreatorPtr> EntityRegistrar;};;  Ah, of course.  (edit: said something stupid so I erased it.)  Still working on function pointer syntax.Also, I'm rather new to much of STL.  Thanks for that correction.  I used to use the [] operator but it's probably better to do an insert, so that's the first code I've written using the map's insert.  It was something I meant to look up because I didn't think that's how it's done.  Thought after adding "make_pair", I get an error; I'll have to look into it.  In RegisterEntityType is says "could not deduce template argument for 'T1' from 'std::string'".And as for your last point, should you really do a "using namespace ..." at the top of every file?  for something like std, I use it in almost every file and it would require that.  Yeah, it does it in a small file that defines some common types and macros.Thanks!   ;Quote:Original post by okonomiyakiAh, of course.  So I could either make the method static or make the changes you made?  I suppose it's better to keep it a member function and make the syntax changes you made.  Thanks.Also, I'm rather new to much of STL.  Thanks for that correction.  I used to use the [] operator but it's probably better to do an insert, so that's the first code I've written using the map's insert.  It was something I meant to look up because I didn't think that's how it's done.  Thought after adding "make_pair", I get an error; I'll have to look into it.  In RegisterEntityType is says "could not deduce template argument for 'T1' from 'std::string'".And as for your last point, should you really do a "using namespace ..." at the top of every file?  for something like std, I use it in almost every file and it would require that.  Yeah, it does it in a small file that defines some common types and macros.Thanks!using namespace ...;i reserve that for .cpp files that make heavy use of loads of namespace std;otherwise i use the using directiveusing std::vector;using std::map;in my header files i prefix all the standard library types and functions with std::   ;  You can use explicit template instantiation with the make_pair function or just manually create the pair object yourself. ex: make_pair<std::string, shared_ptr<AXEntity> >(Name, Entity). Or just use operator[] on the map. Registering a new type shouldn't be on your critical path so a little inefficiency shouldn't make that much of a difference.   