I am creating a template factory for my project, everything was working fine until I need to add an extra parameter to the object creation process.
The factory has two main templates:
template <typename T>
class GenericFactory_c: boost::noncopyable
{
public:
typedef typename T::ObjectType_t ObjectType_t;
//basic creating with just 1 parameter (object name)
ObjectType_t Create(const String_c &className, const String_c &name) const
{
typename ObjectCreatorSet_t::const_iterator it = setObjectCreators.find(className, ObjectCreatorComp_s<T>());
if(it == setObjectCreators.end())
PH_RAISE(OBJECT_NOT_FOUND_EXCEPTION, "[EntityFactory_c::Create]", name);
return it->Create(name);
}
//"advanced" creation using an additional Y parameter
template <typename Y>
ObjectType_t Create(const String_c &className, const String_c &name, Y param) const
{
typename ObjectCreatorSet_t::const_iterator it = setObjectCreators.find(className, ObjectCreatorComp_s<T>());
if(it == setObjectCreators.end())
PH_RAISE(OBJECT_NOT_FOUND_EXCEPTION, "[EntityFactory_c::Create]", name);
return it->Create(name, param);
}
//rest of the code, probably irrelavent to the problem removed for clarity
};
The idea is that for certain types, only the create with 2 parameters will be used, for other types only the create with 3 parameters will be used.
That means that for a certain Factory instantiation, never both versions will be used, just one.
For being able to auto register types using static variables, I created a ObjectCreator class, this is defined as follows:
template <typename T, typename Y>
class ObjectCreatorBase_c: public ObjectCreatorAutoUnlinkHook_t
{
public:
typedef T ObjectType_t;
typedef Y ObjectCreatorProc_t;
public:
ObjectCreatorBase_c(const String_c &name, ObjectCreatorProc_t proc):
strName(name),
pfnCreateProc(proc)
{
}
T Create(const String_c &name) const
{
return pfnCreateProc(name);
}
template <typename Z>
T Create(const String_c &name, Z param) const
{
return pfnCreateProc(name, param);
}
//"irrelevant" code removed
private:
String_c strName;
ObjectCreatorProc_t pfnCreateProc;
};
And for a EntityComponent type that needs two parameters on construtor (string and Entity reference) I define an object creator as below:
template <typename T, typename Y>
class ObjectCreator1_c: public ObjectCreatorBase_c<T, T(*)(const String_c &, Y )>
{
public:
ObjectCreator1_c(const String_c &name, ObjectCreatorProc_t proc):
ObjectCreatorBase_c(name, proc)
{
GenericFactory_c<ObjectCreator1_c >::GetInstance().Register(*this);
}
};
And a creator is defined liked this:
static ObjectCreator1_c<EntityComponentPtr_t, Entity_c &> CreatorForXYZ_CreatorObject_gl("XYZ", &XYZ::Create);
A factory for this is defined like:
typedef GenericFactory_c<ObjectCreator1_c<EntityComponentPtr_t, Entity_c &> > EntityComponentFactory_c;
And finally, for creating a component I use the code below:
Entity_c::CreateCompXYZ()
{
EntityComponentFactory_c &factory = EntityComponentFactory_c::GetInstance();
EntityComponentPtr_t xyz = factory.Create("XYZ", "myXYZInstance", *this);
}
And finally comes my problem, with the code above, the compiler appears to ignore the reference to the *this and tries to create a copy of the Entity object and I get a undefined reference to Entity_c::Entity_c(const Entity_c &), that is ok, because Entity_c does not have a copy constructor (non copyable), but the problem is because this code is not expected to try to copy Entity_c, but uses it references.
Any ideas?
If this function
is actually calling this template for a 3 parameter
Createit really is trying to copy
Entity_c(it beingYhere).Of course this doesn’t work if it is non-copyable!