如果模板化"ResourceCache"需要不同的创建参数/方法,它们如何加载/创建 T 类型的资源?

How can a templated "ResourceCache" load/create resources of type T, if they require different creation parameters/methods?

本文关键字:创建 何加载 加载 资源 类型 ResourceCache 方法 如果 参数      更新时间:2023-10-16

我只是不知道怎么做。

基本上,如果每个模板专用化类型(T)都有不同的初始化参数,那么通用ResourceCache如何加载/创建资源?

template< class T>
class ResourceCache{
  T* cache[100];
  T* LoadResource(different parameters for different  T  ){//used in a cache miss..
          Create( different parameters for different  T );
  }
}

如果我对IResourceParams类使用抽象,如果不使用多态性,我的ResourceCache将无法使用它自己已知的类型资源数据,这有点愚蠢,因为在运行时他知道类型是什么,我在运行时总是在编译时工具的前面做坏事。。。我想。。

在我目前的尝试中,我创建了一个模板化的IResourceDesc,它有一个虚拟的T*Create()方法,所以你需要派生以添加数据并专门化Create方法,但这很糟糕,因为我在ResourceCache类中不能有IResource desc的集合(用于比较当前加载的IResorcceDesc、通过desc获取缓存的资源等)。。。

在C++11中,使用可变模板和完美的转发:非常容易

#include <utility>
template<class... Args>
T* LoadResource(Args&&... args){
  unsigned dest_index = /* pick it */ 0;
  cache[dest_index] = new T(std::forward<Args>(args)...);
  return cache[dest_index];
}

对于C++03,可以提供大约10个不同参数数量的过载,也可以采用现场工厂风格:

template< class T>
class ResourceCache{
  T* cache[100];
  template<class Factory>
  T* LoadResource(Factory const& f){
    unsigned dest_index = /* pick cache slot */ 0;
    void* dest = operator new(sizeof(T));
    cache[dest_index] = f.construct(dest);
    return cache[dest_index];
  }
}
template<class T, class A1>
struct in_place_factory1{
  in_place_factory1(A1 const& a1) : _arg1(a1) {}
  int* construct(void* dest) const{
    return new (dest) T(_arg1);
  }
private:
  A1 const& _arg1; // make sure the original argument outlives the factory
};
// in code
ResourceCache<int> cache;
int arg = 5;
int* res = cache.LoadResource(in_place_factory1<int,int>(arg));

就地工厂基本上是完美转发可变模板函数的劣质版本,它可以将对象直接放置到容器存储中,而不需要一个已经完整的对象进行复制。