I have an Object Factory Class which has a method called registerCreator as defined below:
template < class Base, class Key, typename ObjectCreator = Base* (*)()>
class ObjectFactory
{
public:
bool registerCreator( const Key& id, ObjectCreator creator)
{
return associations_.insert( typename IdToObjectMap::value_type(id, creator)).second != 0;
}
...
private:
typedef std::map<Key, ObjectCreator> IdToObjectMap;
IdToObjectMap associations_;
};
This class is wrapped in a singleton Holder which is essentially implemented following the Loki::SingletonHolder.
I have created a typedef to this as:
typedef SingletonHolder < ObjectFactory < AbstractResource, const char*, AbstractResource* (*)()> > ResourceFactory;
AbstractResource is an empty class for now. I have used another ResourceBase class as follows to help with static polymorphism.
template <class DerivedType>
class ResourceBase
{
public:
virtual ~ResourceBase();
static bool registerWithFactory();
protected:
ResourceBase();
private:
static const bool _Initialized;
};
// this also includes its .C implementation which is as follows:
template <class DerivedType>
const bool ResourceBase<DerivedType>::_Initialized =
ResourceBase<DerivedType>::registerWithFactory();
template<class DerivedType>
bool ResourceBase<DerivedType>::registerWithFactory()
{
if (! _Initialized)
{
return ResourceFactory::Instance().template registerCreator<DerivedType> (DerivedType::className() , &DerivedType::allocate);
}
}
and then my concrete class is as follows: class FileManager : public ResourceBase, AbstractResource { public: FileManager(); ~FileManager() { }
static const char* className();
static AbstractResource* allocate();
};
With FileManager implementation as:
const char* FileManager::className()
{
return "FileManager";
}
AbstractResource* FileManager::allocate()
{
return new FileManager;
}
on compilation, I am getting:
error: no matching function for call to `ObjectFactory<AbstractResource, const char*, AbstractResource*(*)()>::registerCreator(const char*, AbstractResource*(*)())'
Can anyone please suggest what is the issue here? I am missing something very basic as it appears.
The problem is that you call registerCreator using the syntax to call a template member function of a class:
return ResourceFactory::Instance()
.template registerCreator<DerivedType>
(DerivedType::className() , &DerivedType::allocate);
However, registerCreator
is a non-template member function of a template class. After the template class is instantiated (which you did, at the ResourceFactory definition), the non-template function does not need any additional specialization to be called. Ie the following may work, as you can see at http://ideone.com/YIytS (courtesy of @ Lol4t0 ).
return ResourceFactory::Instance()
.registerCreator (DerivedType::className() , &DerivedType::allocate);
template definitions have to be put in the same file as their declaration. Another comment: try to getrid of the typedefs. I just had a.somewhat similar problem and people here managed to rewrite my code without typedefs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.