2010-05-25 23 views
7

C'tor parametreleri için variadic şablonlar kullandığım bir sınıf fabrikam var (aşağıdaki kod). Ancak, kullanmayı denediğimde derleme hataları alıyorum; orijinal olarak parametreler olmadan yazdığımda, iyi çalıştı. İşte C++ Variadic şablonları sorunu olan 0x sınıfı fabrika

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...); 
    } 
}; 

hatadır: Burada

sınıftır çağrılırken (örneğin)

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

GCC 4.5.0 bana verir:

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*))' 

dayana niçin derleme yapamayacağını ve kapsamlı bir ziyaretten sonra cevabı bulamadım. Kim bana yanlış yaptığımı söyler (bağlamda anlam ifade eden garip değişken adından başka)?

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

Bu işlevde Derived kullanmayın, ama muhtemelen GenericFactory<...>.Register(...) çözmek için gcc girişimini kadar kurcalıyor:

+0

Bu sınıflar nasıl yararlıdır? Bu derlendiğinde nasıl kullanılacağına dair basit bir örnek verebilir misiniz? –

+0

Türetilmiş bir sınıfı başlatmanız gerektiğinde, ancak çalışma zamanında yalnızca hangi sınıfa ihtiyacınız olduğunu bilirsiniz. 'Args' parametresi, sınıf kurucusunun argümanları olduğunda içindir. – user350096

+0

"GenericFactory" sorusunun içerdiği kodda, şablonlu bir sınıf bile yok. Sanırım herhangi bir yardım almak için tamir etmelisin. – doublep

cevap

2

Buranın barfing düşünüyorum. Bunu da GenericFactory<...>::Register(...) olarak değiştirmek isteyebilirsiniz.

+0

Teşekkürler, işe yaradı. Basit bir şey olması gerektiğini biliyordum! – user350096

İlgili konular