2012-01-29 78 views
0

我已如下文所定義,其具有稱爲registerCreator方法的對象工廠類:C++:模板 - 無匹配功能調用

template < class Base, class Key, typename ObjectCreator = Base* (*)()> 

class ObjectFactory 

{ 

     public: 
     bool registerCreator(const Key& id, ObjectCreator creator) 
     { 
      return associations_.insert(typename IdToObjectMap::value_type(id, creator)).second != 0; 
     } 
     ... 
     private: 
     typedef std::map<Key, ObjectCreator> IdToObjectMap; 
     IdToObjectMap associations_; 

}; 

此類包裝在單架其基本上實現以下洛基:: SingletonHolder。

我創建了一個typedef此爲:

typedef SingletonHolder < ObjectFactory < AbstractResource, const char*, AbstractResource* (*)()> > ResourceFactory; 

AbstractResource是一個空類現在。 我已經使用了另一個ResourceBase類來幫助靜態多態。

template <class DerivedType> 
class ResourceBase 
{ 
    public: 
    virtual ~ResourceBase(); 
    static bool registerWithFactory(); 

    protected: 

    ResourceBase(); 

    private: 

    static const bool _Initialized; 
}; 

//這也包括了.C實現其如下:

template <class DerivedType> 
const bool ResourceBase<DerivedType>::_Initialized = 
ResourceBase<DerivedType>::registerWithFactory(); 

template<class DerivedType> 
bool ResourceBase<DerivedType>::registerWithFactory() 
{ 
    if (! _Initialized) 
    { 
    return ResourceFactory::Instance().template registerCreator<DerivedType> (DerivedType::className() , &DerivedType::allocate); 
    } 
} 

,然後我的具體類別如下: 類文件管理:公共ResourceBase,AbstractResource { 市民: FileManager(); 〜文件管理器(){}

static const char* className(); 
    static AbstractResource* allocate(); 
}; 

隨着文件管理器實現爲:

const char* FileManager::className() 
{ 
    return "FileManager"; 
} 

AbstractResource* FileManager::allocate() 
{ 
    return new FileManager; 
} 

在編譯時,我得到:

error: no matching function for call to `ObjectFactory<AbstractResource, const char*, AbstractResource*(*)()>::registerCreator(const char*, AbstractResource*(*)())' 

任何人都可以請建議有什麼問題嗎?我錯過了一些非常基本的東西。

+0

這是一個額外的撇號嗎? 'typedef SingletonHolder' Borealid 2012-01-29 08:41:33

+0

在定義'SingletonHolder'和'AbstractResource'後,您的代碼完美編譯:http://ideone.com/wcSjx – Lol4t0 2012-01-29 09:05:28

+0

將代碼複製到單個文件併爲未定義類型添加存根後, :http://ideone.com/kD52i。你認爲你可以編寫你的代碼到一個可編譯的測試用例嗎? – user450018 2012-01-29 09:05:31

回答

1

的問題是,你叫registerCreator使用語法來調用類的模板成員函數:

return ResourceFactory::Instance() 
     .template registerCreator<DerivedType> 
     (DerivedType::className() , &DerivedType::allocate); 

然而,registerCreator是一個模板類的非模板成員函數。在模板類被實例化之後(你在ResourceFactory定義的過程中),非模板函數不需要任何額外的特化來調用。即以下內容可能會有效,正如你可以在http://ideone.com/YIytS中看到的(禮貌@Lol4t0)。

return ResourceFactory::Instance() 
     .registerCreator (DerivedType::className() , &DerivedType::allocate); 
+0

謝謝Alexey。你是對的,它解決了這個問題。 – notifyroy 2012-01-29 14:05:11

0

模板定義必須放在與其聲明相同的文件中。另一個評論:嘗試gendid typedefs。我只是遇到了一些類似的問題,並且這裏的人設法在不使用typedefs的情況下重寫我的代碼。