This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Template Function Seemingly Nonexistent


I have a generic class factory (shown below).  From within some CPP file
that implements some object's methods, I have two separate functions
that call the RegisterClass() function in the instantiated class
factory.  The first function compiles properly and has no problems
calling the RegisterClass() function.  However, the second function that
calls RegisterClass() generates a compiler error "no matching function
for call to `CKClassFactory<CKCommand>::RegisterClass(const
CKClassFactory<CKCommand>::CKClassCreator<CLCCommandA>&)'"  If I switch
the position of the two functions that call RegisterClass(), the first
one always compiles, while the second does not.  Thus, I know there is
not a syntax error or some problem with the calling function itself.
Function2 will compile if it comes first in the file.  The class factory
is being used as follows (the second function generates the error):

typedef CKClassFactory<CKCommand> CKCommandFactory;

CKCommandFactory	theFactory;

Function1()
{
	const CKCommandFactory::CKClassCreator<CLCCommandA>
creator(1, "CLCCommandA");
	theFactory.RegisterClass(creator);
}

Function2()
{
	const CKCommandFactory::CKClassCreator<CLCCommandB>
creator(2, "CLCCommandB");
	theFactory.RegisterClass(creator);
}

template <class ReturnType>
class CKClassFactory : public CKObject
{
private:
  // The base class creator class. Not used for anything but
  // some variable storage and the base Create() function.
  class CKBaseCreator
  {
	public:
		TK_UINT32 m_id;
		CKString m_strTypeName;
	public:
		virtual ReturnType* Create() = 0;
  };
public:

	// The derived class creator object that actually creates the
classes. 
	// There is one of these for each registered class.
	template <class ClassType>
	class CKClassCreator : public CKBaseCreator
	{
	public:
		// Called to create the class type.
		ReturnType* Create()
		{
			return (ReturnType*)(new ClassType);
		}
		CKClassCreator(TK_UINT32 id, TK_CPINT8 pcTypeName)
		{
			m_id = id;
			m_strTypeName = pcTypeName;
		}
	};
protected:
	typedef std::map<TK_UINT32, CKBaseCreator*> FnRegistry; // A
typedef'd map.
	FnRegistry m_mapCreatorFunctions; // The actual command
registry.
public:
	CKClassFactory(){}
	~CKClassFactory()
	{
		FnRegistry::iterator iter;
		for (iter = m_mapCreatorFunctions.begin(); iter !=
m_mapCreatorFunctions.end(); iter++)
		{
			CKBaseCreator* pCreator = iter->second;
			delete pCreator;
		}
	}
	// Call this to register a class with the factory. You must
supply a prototype class
	// class creator for the factory to work from.
	// You can call IsRegistered() to determine if the class ID is
in use.
	template <class T> void RegisterClass(const CKClassCreator<T>&
rPrototype)
	{
		// Don't register two of the same ID.
		if (!IsRegistered(rPrototype.m_id))
		{
			CKClassCreator<T>* pCreator = new
CKClassCreator<T>(rPrototype.m_id, rPrototype.m_strTypeName);
			m_mapCreatorFunctions[rPrototype.m_id] =
pCreator;
		}
	}
	// Call this to create a class of the specified type ID.
	ReturnType* Create(TK_UINT32 uiClassID) const
	{
		FnRegistry::const_iterator iter;
		if ((iter = m_mapCreatorFunctions.find(uiClassID)) !=
m_mapCreatorFunctions.end())
		{
			CKBaseCreator* pCreator = iter->second;
			return pCreator->Create();
		}
		return NULL;
	}
	// Used to determine if a given class ID is already in use by
the factory.
	TK_BOOL8 IsRegistered(TK_UINT32 uiClassID) const
	{
		FnRegistry::const_iterator iter;
		if ((iter = m_mapCreatorFunctions.find(uiClassID)) !=
m_mapCreatorFunctions.end())
		{
			return true;
		}
		return false;
	}
	// Call this to retrieve the class type name associated with the
specified class ID.
	TK_CPINT8 GetTypeName(TK_UINT32 uiClassID) const
	{
		FnRegistry::const_iterator iter;
		if ((iter = m_mapCreatorFunctions.find(uiClassID)) !=
m_mapCreatorFunctions.end())
		{
			CKBaseCreator* pCreator = iter->second;
			return pCreator->m_strTypeName;
		}
		return NULL;
	}
protected:
};


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]