#include <iostream>
#include <map>
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_;
} ;
struct AbstractResource { } ;
template < typename T>
struct SingletonHolder
{
static T Instance( ) { return T( ) ; }
} ;
typedef SingletonHolder < ObjectFactory < AbstractResource, const char * , AbstractResource* ( * ) ( ) > > ResourceFactory;
template < class DerivedType>
class ResourceBase
{
public :
virtual ~ResourceBase( ) { }
static bool registerWithFactory( ) ;
static bool isInitialized( ) { return _Initialized; }
protected :
ResourceBase( ) { }
private :
static const bool _Initialized;
} ;
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 ) ;
}
}
struct FileManager: public ResourceBase< FileManager> , AbstractResource {
static const char * className( ) { return "FileManager" ; }
static AbstractResource* allocate( ) { return new FileManager; } ;
} ;
int main( )
{
FileManager f;
std:: cout << f.isInitialized ( ) << std:: endl ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgoKdGVtcGxhdGUgPCBjbGFzcyBCYXNlLCBjbGFzcyBLZXksIHR5cGVuYW1lIE9iamVjdENyZWF0b3IgPSBCYXNlKiAoKikoKT4KY2xhc3MgT2JqZWN0RmFjdG9yeQp7CiAgICAgIHB1YmxpYzoKICAgICAgICBib29sIHJlZ2lzdGVyQ3JlYXRvciggY29uc3QgS2V5JiBpZCwgT2JqZWN0Q3JlYXRvciBjcmVhdG9yKQogICAgICAgIHsKICAgICAgICAgIHJldHVybiBhc3NvY2lhdGlvbnNfLmluc2VydCggdHlwZW5hbWUgSWRUb09iamVjdE1hcDo6dmFsdWVfdHlwZShpZCwgY3JlYXRvcikpLnNlY29uZCAhPSAwOwogICAgICAgIH0KICAgICAgcHJpdmF0ZToKICAgICAgICB0eXBlZGVmIHN0ZDo6bWFwPEtleSwgT2JqZWN0Q3JlYXRvcj4gSWRUb09iamVjdE1hcDsKICAgICAgICBJZFRvT2JqZWN0TWFwIGFzc29jaWF0aW9uc187Cn07CgpzdHJ1Y3QgQWJzdHJhY3RSZXNvdXJjZSB7fTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgU2luZ2xldG9uSG9sZGVyCnsKCXN0YXRpYyBUIEluc3RhbmNlKCkgeyByZXR1cm4gVCgpOyB9Cn07CnR5cGVkZWYgU2luZ2xldG9uSG9sZGVyIDwgT2JqZWN0RmFjdG9yeSA8IEFic3RyYWN0UmVzb3VyY2UsIGNvbnN0IGNoYXIqLCBBYnN0cmFjdFJlc291cmNlKiAoKikoKT4gPiBSZXNvdXJjZUZhY3Rvcnk7Cgp0ZW1wbGF0ZSA8Y2xhc3MgRGVyaXZlZFR5cGU+CmNsYXNzIFJlc291cmNlQmFzZQp7CiAgcHVibGljOgogICAgdmlydHVhbCB+UmVzb3VyY2VCYXNlKCkge30KICAgIHN0YXRpYyBib29sIHJlZ2lzdGVyV2l0aEZhY3RvcnkoKTsKICAgIHN0YXRpYyBib29sIGlzSW5pdGlhbGl6ZWQoKSB7IHJldHVybiBfSW5pdGlhbGl6ZWQ7IH0KICBwcm90ZWN0ZWQ6CiAgICBSZXNvdXJjZUJhc2UoKSB7fQogIHByaXZhdGU6CiAgICBzdGF0aWMgY29uc3QgYm9vbCBfSW5pdGlhbGl6ZWQ7Cn07Cgp0ZW1wbGF0ZSA8Y2xhc3MgRGVyaXZlZFR5cGU+CmNvbnN0IGJvb2wgUmVzb3VyY2VCYXNlPERlcml2ZWRUeXBlPjo6X0luaXRpYWxpemVkID0gIFJlc291cmNlQmFzZTxEZXJpdmVkVHlwZT46OnJlZ2lzdGVyV2l0aEZhY3RvcnkoKTsKCnRlbXBsYXRlPGNsYXNzIERlcml2ZWRUeXBlPgpib29sIFJlc291cmNlQmFzZTxEZXJpdmVkVHlwZT46OnJlZ2lzdGVyV2l0aEZhY3RvcnkoKQp7CiAgaWYgKCEgX0luaXRpYWxpemVkKQogIHsKICAgIHJldHVybiBSZXNvdXJjZUZhY3Rvcnk6Okluc3RhbmNlKCkudGVtcGxhdGUgcmVnaXN0ZXJDcmVhdG9yPERlcml2ZWRUeXBlPiAgICAoRGVyaXZlZFR5cGU6OmNsYXNzTmFtZSgpICwgJkRlcml2ZWRUeXBlOjphbGxvY2F0ZSk7CiAgfQp9CgpzdHJ1Y3QgRmlsZU1hbmFnZXI6IHB1YmxpYyBSZXNvdXJjZUJhc2U8RmlsZU1hbmFnZXI+LCBBYnN0cmFjdFJlc291cmNlIHsKICAgIHN0YXRpYyBjb25zdCBjaGFyKiBjbGFzc05hbWUoKSB7IHJldHVybiAiRmlsZU1hbmFnZXIiOyB9CiAgICBzdGF0aWMgQWJzdHJhY3RSZXNvdXJjZSogYWxsb2NhdGUoKSB7IHJldHVybiBuZXcgRmlsZU1hbmFnZXI7IH07Cn07CgppbnQgbWFpbigpCnsKICAgIEZpbGVNYW5hZ2VyIGY7CiAgICBzdGQ6OmNvdXQgPDwgZi5pc0luaXRpYWxpemVkKCkgPDwgc3RkOjplbmRsOwogICAgcmV0dXJuIDA7ICAgCn0K
compilation info
prog.cpp: In static member function ‘static bool ResourceBase<DerivedType>::registerWithFactory() [with DerivedType = FileManager]’:
prog.cpp:40: instantiated from ‘const bool ResourceBase<FileManager>::_Initialized’
prog.cpp:32: instantiated from ‘static bool ResourceBase<DerivedType>::isInitialized() [with DerivedType = FileManager]’
prog.cpp:59: instantiated from here
prog.cpp:47: error: no matching function for call to ‘ObjectFactory<AbstractResource, const char*, AbstractResource* (*)()>::registerCreator(const char*, AbstractResource* (*)())’
stdout