C++ C++;获取模板参数包中的第一个参数值

C++ C++;获取模板参数包中的第一个参数值,c++,c++11,C++,C++11,我有这门课 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) {

我有这门课

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

继承Asset的类可能有不同数量的参数,因此我试图捕获第一个参数的值,因为它将始终是一个std::string路径,正如您在Asset类构造函数中看到的那样。

如果您的第一个参数始终是一个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)]);
}
模板
bool newAsset(const std::string&path,Args&&…Args)
{   
//获取路径
if(缓存的(路径)){return true;}
auto asset=new T{path,std::forward(在“notes”下)。最好使用
typeid.hash\u code()

  • 将路径设为强制参数,现在您可以在执行
    cached
    查找时引用它
  • 将路径和其余参数一起传递给
    Asset
    构造函数

模板
bool newAsset(const std::string&path,Args&&…Args)
{   
if(缓存的(路径)){return true;}
auto asset=newt{path,std::forward(args)…};
资产[&typeid(*资产)]=资产;
返回*static_cast(资产[&typeid(T)]);
}

如果我告诉你只在args之前声明一个std::string参数,这是不是太简单了,因为它是强制性的?是的,这样做吧。否则你就无法强制执行人们选择在包中传递的内容。为什么要费心留着出错的可能性呢?建议
bool newAsset(args&&…args)
以正确支持完美转发。如果没有
&&
,您总是在复制参数。在遵循@ascheplers建议的同时,还将基于范围的循环更改为
自动&
。顺便说一句,返回类型是可疑的,可能应该是
T&
。返回
*资产
也可以避免强制转换和不必要的extra抬起头来。我想我会坚持这个解决方案。谢谢:)
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)]);
}
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)]);
}