2010-05-25 9 views
7

Tengo una fábrica de clases donde estoy usando plantillas variadic para los parámetros de c'tor (código debajo). Sin embargo, cuando intento usarlo, obtengo errores de compilación; cuando originalmente lo escribí sin parámetros, funcionó bien.C++ fábrica de la clase 0x con problema de plantillas variadic

Aquí es la clase:

template< class Base, typename KeyType, class... Args > 
class GenericFactory 
{ 
public: 
    GenericFactory(const GenericFactory&) = delete; 
    GenericFactory &operator=(const GenericFactory&) = delete; 

    typedef Base* (*FactFunType)(Args...); 

    template <class Derived> 
    static void Register(const KeyType &key, FactFunType fn) 
    { 
     FnList[key] = fn; 
    } 

    static Base* Create(const KeyType &key, Args... args) 
    { 
     auto iter = FnList.find(key); 
     if (iter == FnList.end()) 
     return 0; 
     else 
     return (iter->second)(args...); 
    } 

    static GenericFactory &Instance() { static GenericFactory gf; return gf; } 
private: 
    GenericFactory() = default; 

    typedef std::unordered_map<KeyType, FactFunType> FnMap; 
    static FnMap FnList; 
}; 

template <class B, class D, typename KeyType, class... Args> 
class RegisterClass 
{ 
public: 
    RegisterClass(const KeyType &key) 
    { 
     GenericFactory<B, KeyType, Args...>::Instance().Register(key, FactFn); 
    } 
    static B *FactFn(Args... args) 
    { 
     return new D(args...); 
    } 
}; 

Aquí está el error: al llamar (por ejemplo)

// Tucked out of the way 
RegisterClass<DataMap, PDColumnMap, int, void *> RC_CT_PD(0); 

GCC 4.5.0 me da:

In constructor 'RegisterClass<B, D, KeyType, Args>::RegisterClass(const KeyType&) [with B = DataMap, D = PDColumnMap, KeyType = int, Args = {void*}]': 
no matching function for call to 'GenericFactory<DataMap, int, void*>::Register(const int&, DataMap* (&)(void*))' 

lo que pueda' Veo por qué no se compilará y después de una extensa búsqueda en Google no pude encontrar la respuesta. ¿Alguien puede decirme qué estoy haciendo mal (aparte del extraño nombre de variable, que tiene sentido en contexto)?

+0

¿Cómo son útiles estas clases? ¿Puede proporcionar un ejemplo simple de cómo se usarían si se compila? –

+0

Es para cuando necesita instanciar una clase derivada pero solo sabe qué clase necesita en tiempo de ejecución. El parámetro 'Args' es para cuando el constructor de clase tiene argumentos. – user350096

+0

En el código incluido en la pregunta 'GenericFactory' ni siquiera es una clase de plantilla. Supongo que deberías arreglarlo para obtener ayuda. – doublep

Respuesta

2

Creo que es barfing aquí:

template <class Derived> 
static void Register(const KeyType &key, FactFunType fn) 
{ 
    FnList[key] = fn; 
} 

no utiliza Derived en esta función, pero probablemente está jugando hasta el intento de gcc para resolver GenericFactory<...>.Register(...). También es posible que desee cambiar eso a GenericFactory<...>::Register(...).

+0

Gracias, eso funcionó. ¡Sabía que tenía que ser algo simple! – user350096

Cuestiones relacionadas