i have some code like this:
// Factory.h
typedef std::uint8_t FactoryId;
const FactoryId FACTORY_ID_MAX_VALUE = UINT8_MAX;
template <typename TBaseProduct>
class IFactory {
public:
virtual TBaseProduct* create() = 0;
};
template <typename TProduct, typename TBaseProduct>
class Factory : public IFactory<TBaseProduct> {
public:
virtual TBaseProduct* create() override {
return new TProduct;
}
};
template <typename TProduct, typename TBaseProduct>
class FactoryProduct : public TBaseProduct {
public:
static Factory<TProduct, TBaseProduct> factory;
};
template <typename TFactoryTable, typename TBaseProduct>
class FactoryTable {
public:
typedef IFactory<TBaseProduct> BaseFactory;
typedef BaseFactory* BaseFactoryPtr;
FactoryTable(): factorys(nullptr) {}
~FactoryTable() { delete[] factorys; }
BaseFactory& get(FactoryId factoryId) {
if (factoryId > maxFactoryId) {
throw std::exception("out of range");
}
return *factorys[factoryId];
}
protected:
template <std::size_t factoryCount>
void init(BaseFactoryPtr (&factorys)[factoryCount]) {
init(factorys, factoryCount);
}
void init(BaseFactoryPtr* factorys, std::size_t factoryCount) {
assert(factorys != nullptr);
assert(factoryCount > 0 && factoryCount - 1 <= FACTORY_ID_MAX_VALUE);
this->factorys = new BaseFactoryPtr[factoryCount];
std::memcpy(this->factorys, factorys, sizeof(BaseFactoryPtr) * factoryCount);
this->maxFactoryId = factoryCount - 1;
}
private:
BaseFactoryPtr* factorys;
FactoryId maxFactoryId;
};
// Foo.h
class BaseFoo {};
class Foo1 : public FactoryProduct<Foo1, BaseFoo> {};
class Foo2 : public FactoryProduct<Foo2, BaseFoo> {};
class FooFactoryTable : public FactoryTable<FooFactoryTable, BaseFoo> {
public:
FooFactoryTable() {
IFactory<BaseFoo>* table[] = {
&Foo1::factory,
&Foo2::factory,
};
init(table);
}
};
in order to provide a factory array to init FactoryTable<>, i have to manually create an array (IFactory* table[]) in FooFactoryTable. so i use variadic template to avoid this:
template <typename TFactoryTable, typename TBaseProduct, typename... MTProduct>
class FactoryTable {
// the visible of the two init() is changed from protected to private.
// except this, the only changed member is the constructor
FactoryTable(): factorys(nullptr) {
IFactory<BaseFoo>* table[] = {
(&MTProduct::factory)...
};
init(table);
}
};
so that i can simply implement "FooFactoryTable" like this, and hide FooFactoryTable's knowledge about "FactoryProduct<>::factory"
class FooFactoryTable : public FactoryTable<FooFactoryTable, BaseFoo,
Foo1,
Foo2> {};
my question is, is there another way to implement "FactoryTable" without using variadic template? because variadic template is not supported by visual studio 2012(v110), and "'Microsoft Visual C++ Compiler Nov 2012 CTP' is for testing purposes only.". i worry other compilers may also have the same problem as visual studio 2012(v110). the "other compilers" is those compilers that targeting android or iphone.
note that: the main reason for re-implementing "FactoryTable" is to make FooFactoryTable as simpler as possible.