C++ 是否有可变模板的替代方案

C++ 是否有可变模板的替代方案,c++,variadic-templates,C++,Variadic Templates,我有一些这样的代码: //工厂 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 TB

我有一些这样的代码:

//工厂

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;
};
typedef std::uint8\u t FactoryId;
const FactoryId FACTORY\u ID\u MAX\u VALUE=UINT8\u MAX;
模板
类工厂{
公众:
虚拟TBaseProduct*create()=0;
};
模板
类别工厂:公共工厂{
公众:
虚拟TBaseProduct*创建()覆盖{
返回新产品;
}
};
模板
类别FactoryProduct:公共TBaseProduct{
公众:
静电厂;
};
模板
类FactoryTable{
公众:
typedef IFactory基地工厂;
类型定义BaseFactory*BaseFactoryPtr;
FactoryTable():factorys(nullptr){}
~FactoryTable(){delete[]factorys;}
BaseFactory&get(FactoryId FactoryId){
如果(factoryId>maxFactoryId){
抛出标准::异常(“超出范围”);
}
return*factorys[factoryId];
}
受保护的:
模板
void init(BaseFactoryPtr(&factorys)[factoryCount]){
init(factorys,factoryCount);
}
void init(BaseFactoryPtr*factorys,std::size\u t factoryCount){
断言(factorys!=nullptr);
断言(factoryCount>0&&factoryCount-1 factorys=new BaseFactoryPtr[factoryCount];
std::memcpy(此->工厂,工厂,sizeof(BaseFactoryPtr)*factoryCount);
此->maxFactoryId=factoryCount-1;
}
私人:
BaseFactoryPtr*工厂;
FactoryId最大FactoryId;
};
//福安

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);
    }
};
classbasefoo{};
类别1:公共工厂产品{};
类别2:公共工厂产品{};
FooFactoryTable类:公共FactoryTable{
公众:
FoodFactoryTable(){
IFactory*表[]={
&Foo1::工厂,
&工厂,
};
init(表);
}
};
为了向init FactoryTable提供工厂数组,我必须在FooFactoryTable中手动创建一个数组(IFactory*table[])。因此我使用可变模板来避免这种情况:

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);
    }
};
模板
类FactoryTable{
//两个init()的可见项从protected更改为private。
//除此之外,唯一更改的成员是构造函数
FactoryTable():factorys(nullptr){
IFactory*表[]={
(&MTProduct::factory)。。。
};
init(表);
}
};
这样我就可以像这样简单地实现“FooFactoryTable”,并隐藏FooFactoryTable关于“FactoryProduct::factory”的知识

类FooFactoryTable:PublicFactoryTable{};
P>我的问题是,是否有另一种方法来实现“FaseYTABLE”而不使用VulaseDead模板?因为VisualStudio 2012(V110)不支持VALIDAY模板,而“MyStVisualVisual C++编译器NOV 2012 CTP”仅用于测试。“我担心其他编译器可能也会遇到VisualStudio 2012(V110)相同的问题。“其他编译器”是指那些针对android或iphone的编译器


请注意:重新实现“FactoryTable”的主要原因是使FooFactoryTable尽可能简单。

使用VS2013 RC。它支持可变模板。所有针对其他当前移动平台的编译器也是如此


不要绕过不受支持的功能,你只会遇到令人讨厌的攻击,而这些攻击并不完全符合你的要求。

Visual Studio确实支持“人造”可变模板,最多允许5-10个(默认情况下为8个)参数。除非您确实需要使用大量类型参数实例化模板,否则您可以在VS2012中使用variadics。

是的,请参阅boost mpl。实际上,它使用链式对替换variardic,使用宏创建小的伪variardic。我们讨论的类型有多少?还有其他方法。另外,如果你所说的其他编译器是GCC和CLAN——他们对新C++特性的支持通常优于VC++。自从4.3以来,可变模板已经在GCC中出现了,自从2.9以来,在Clang,它们都已经发布了多个稳定版本。在GCC标准库实现中,过多的编译时间迫使支持的参数的最大数量从原来的二十个恢复到十个,这是标准草案[10]允许的最小值。(jot.fm/issues/issue_2008_02/article2)@ Us2012 VS2012支持与GCC 4.3相同的10种类型的参数。GCC由于变量的标准最近发生了变化,因此不能正确的支持变量(对于Visual Studio 2012发布来说太晚了)。最后的C++ 11标准在2011年中发布。@方舟是指:如果我想要无限的计数(至少UIT88MAX)。对于类型参数,我可能不使用可变模板。即使编译器支持可变模板,编译时间也可能太长。gcc4.8或4.7.x呢?
class FooFactoryTable : public FactoryTable<FooFactoryTable, BaseFoo, 
    Foo1,
    Foo2> {};