Первоначально задача была сформулированна в этом топике:
http://rsdn.ru/Forum/Message.aspx?mid=238443Автор: Sergeem
Дата: 10.04.03
Имеем вот такую иерархию шаблонных классов. Где статический метод TryCreateObject создаёт экземпляры для всех допустимых значений входного парамерта.
class Base{};
template<int tParam> class A: public Base
{
A(){};
public:
static Base* TryCreateObject()
{
return (tParam > 2 && tParam < 14) ? new A<tParam> : 0;
};
};
template<int tParam> class B: public Base
{
B(){};
public:
static Base* TryCreateObject()
{
return (tParam < 12) ? new B<tParam> : 0;
};
};
template<int tParam> class C: public Base
{
C(){};
public:
static Base* TryCreateObject()
{
return (tParam < 10) ? new C<tParam> : 0;
};
};
Требуется динамически создавать тот или иной объект, в зависимости от 2 переменных:
1) — идентификатор класса
2) — парамерт класса.
Для этого вот такая функция:
Base* TryCreateParamObject(int classID, int param)
{
static const unsigned max_param = 32;
if (0 > param || param > max_param)
return 0;
return GetParamClass<0, max_param>::TryCreateObject(classID, param);
};
Ну и конечно бинарным поиском определяем параметризованный класс и вызывает соответствующий TryCreateObject():
template<unsigned tMin, unsigned tMax>
struct GetParamClass
{
enum { eParam = (tMin+tMax)/2};
static Base* TryCreateObject(int classID, int param)
{
return (param == eParam) ? TryCreateObject(classID) :
(param > eParam) ? GetParamClass<eParam, tMax>::TryCreateObject(classID, param):
GetParamClass<tMin, eParam>::TryCreateObject(classID, param);
};
static Base* TryCreateObject(int classID)
{
switch (classID)
{
case 1: return A<eParam>::TryCreateObject();
case 2: return B<eParam>::TryCreateObject();
case 3: return C<eParam>::TryCreateObject();
}
return 0;
};
};
Теперь можно пытаться создавать объекты:
int nCID = 1;
int nParam = 3;
Base *pBase = TryCreateParamObject(nCID, nParam);
P.S.: VC6.0 compatible!