2016-07-25 99 views
-1

第一個參數值,我有這個類C++得到模板參數包

class AssetManager 
{ 
private: 
    std::unordered_map<const std::type_info*, Asset*> assets; 

public: 
    AssetManager(); 
    virtual ~AssetManager(); 

    template <typename T, typename ...Args> 
    bool newAsset(Args... args) 
    { 
     //Get path 
     if(cached(path)) { return true; } 

     auto asset = new T{ std::forward<Args>(args)... }; 
     assets[&typeid(*asset)] = asset; 
     return *static_cast<T*>(assets[&typeid(T)]); 
    } 

    bool cached(const std::string& path) 
    { 
     for(auto asset : assets) { 
      if(asset.second->getPath() == path) { 
      return true; 
      } 
     } 

     return false; 
    } 
}; 

所有資產的第一個參數將始終的std :: string路徑。 我試圖得到這個值,看看它是否已經加載到列表中。 資產是一個抽象類。

class Asset 
{ 
private: 
    std::string path; 

public: 
    Asset(const std::string& path); 
    virtual ~Asset() = default; 
    virtual bool load() = 0; 
    std::string getPath(); 
}; 

類繼承的資產可能有不同數量的參數,因此我試圖捕捉到第一個參數的值,因爲它永遠是一個的std :: string路徑,你可以在資產類別看構造函數。

+5

如果我告訴你只是在args之前聲明一個std :: string參數,假設它是強制性的,那麼我是否完全過於簡單? –

+1

是的,那樣做。否則,你不能執行人們選擇通過的一切。爲什麼要留下做錯的可能性? –

+4

建議'bool newAsset(Args && ... args)'正確支持完美轉發。沒有'&&',你總是在抄襲你的論點。 – aschepler

回答

5

如果你的第一個參數總是一個std :: string,那麼聲明它就很有意義。首先,它解決了這個問題。另一方面,它確保呼叫者永遠不會錯誤。如果您在資產的構造函數中也需要它,可以將其單獨傳遞給該構造函數,也可以在其中聲明它。

template <typename T, typename ...Args> 
bool newAsset(const std::string &path, Args&&... args) 
{ 
    //Get path 
    if(cached(path)) { return true; } 

    auto asset = new T{ path, std::forward<Args>(args)... }; 
    assets[&typeid(*asset)] = asset; 
    return *static_cast<T*>(assets[&typeid(T)]); 
} 

我也想知道你使用typeid;你是否絕對肯定使用它作爲地圖中的關鍵字是正確的?我沒有看到任何運營商<,並且運算符==不能保證根據http://en.cppreference.com/w/cpp/language/typeid(在「註釋」下)給出一致的結果。代替使用typeid.hash_code()可能會更好。

+0

猜猜我會堅持這個解決方案。謝謝 :) – vegeta

0
  • 製作路徑強制參數,現在你可以參考它,當你做你的cached查找
  • 傳遞路徑和參數的其它國家一道,以您的Asset構造

template <typename T, typename ...Args> 
bool newAsset(const std::string& path, Args&&... args) 
{ 
    if(cached(path)) { return true; } 

    auto asset = new T{ path, std::forward<Args>(args)... }; 
    assets[&typeid(*asset)] = asset; 
    return *static_cast<T*>(assets[&typeid(T)]); 
}