2016-07-25 32 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)]); 
}