C++ C++;具有内置缓存的对象工厂-阴影模板参数

C++ C++;具有内置缓存的对象工厂-阴影模板参数,c++,objectfactory,C++,Objectfactory,我有一个数据库类,它应该提供一个模板方法来返回表示表的存储库对象。每个存储库只能存在一次。我找到了一个示例,但我希望有一个内置缓存 database.h标题如下所示: class Database { public: Database(const char *connectionString); template<typename T> shared_ptr<class T : RepositoryBase> GetRepository(); private:

我有一个数据库类,它应该提供一个模板方法来返回表示表的存储库对象。每个存储库只能存在一次。我找到了一个示例,但我希望有一个内置缓存

database.h
标题如下所示:

class Database
{
public:
  Database(const char *connectionString);
  template<typename T> shared_ptr<class T : RepositoryBase> GetRepository();

private:
  sqlite3* _connection;
  map<string, RepositoryBase> _repositoryCache;
};
我想这样称呼它:

// SampleRepository is derived from RepositoryBase
shared_ptr<SampleRepository> sampleRepo = GetRepository<SampleRepository>();
我需要在template方法中将什么更改为不隐藏任何模板参数


更新

根据NathanOliver的建议,模板方法如下所示:

template<typename T> shared_ptr<class T : RepositoryBase> Database::GetRepository()
{
  string name = typeid(T).name();

  if(_repositoryCache.count(name) == 0)
  {
    _repositoryCache[name] = shared_ptr<T>(new T(_connection));
  }

  return _repositoryCache[name];
}
template<typename T, typename enable_if<is_base_of<RepositoryBase, T>::value>::type* = nullptr> shared_ptr<T> Database::GetRepository()
{
  string name = typeid(T).name();

  if(_repositoryCache.count(name) == 0)
  {
    _repositoryCache[name] = shared_ptr<T>(new T(_connection));
  }

  return _repositoryCache[name]();
}
它指向模板签名中的
nullptr


更新2

根据@NathanOliver给出的答案,我尝试了几种参数组合。我仍然得到了错误:

error : declaration of 'T' shadows template parameter
error : template parameter redefines default argument
1>C:\..\Database.cpp(65,98): error : template parameter redefines default argument
1>template<typename T, typename std::enable_if<std::is_base_of<RepositoryBase, T>::value>::type* = nullptr> std::shared_ptr<T> Database::GetRepository()
1>                                                                                                 ^
1>C:\..\Database.h(25,108) :  note: previous default template argument defined here
1>          template<typename T, typename std::enable_if<std::is_base_of<RepositoryBase, T>::value>::type* = nullptr> std::shared_ptr<T> GetRepository();
1>                                                                                                           ^

这里的问题是

template<typename T> shared_ptr<class T : RepositoryBase> GetRepository();

这里的问题是

template<typename T> shared_ptr<class T : RepositoryBase> GetRepository();


数据库是否已模板化?如果是这样,
模板
部分看起来像什么?不是。只有在数据库头文件中可以看到模板化的
GetRepository
函数。您试图用
共享的ptr
做什么?你是想说
T
需要从
RepositoryBase
派生吗?
shared\u ptr
看起来像Java的泛型。这个不是C++,因此是错误的。+注意用<代码> map < /COD>进行切片。是<代码>数据库< /代码>模板化的吗?如果是这样,
模板
部分看起来像什么?不是。只有在数据库头文件中可以看到模板化的
GetRepository
函数。您试图用
共享的ptr
做什么?你是想说
T
需要从
RepositoryBase
派生吗?
shared\u ptr
看起来像Java的泛型。这不是C++,因此是错误的。+注意用代码<图>代码>的切片。谢谢你的回应。在我看来,这是我想要的。但是我得到了以下错误:
error:template参数重新定义了默认参数
,它指向模板签名中的
nullptr
。实现是否需要在定义的头中看起来有所不同?@BrunoBieri应该是这样的:感谢您提供示例代码!我还是不明白。我得到了错误:模板参数重新定义了默认参数。有什么提示会导致什么吗?据我所知,clang不允许有头文件和我在这里学到的实现:@brunobieri看起来你在头文件和CPP文件之间拆分模板代码。你不能那样做。谢谢你的回复。在我看来,这是我想要的。但是我得到了以下错误:
error:template参数重新定义了默认参数
,它指向模板签名中的
nullptr
。实现是否需要在定义的头中看起来有所不同?@BrunoBieri应该是这样的:感谢您提供示例代码!我还是不明白。我得到了错误:模板参数重新定义了默认参数。有什么提示会导致什么吗?据我所知,clang不允许有头文件和我在这里学到的实现:@brunobieri看起来你在头文件和CPP文件之间拆分模板代码。你不能那样做。
template<typename T, typename std::enable_if<std::is_base_of<RepositoryBase, T>::value>::type* = nullptr> 
shared_ptr<T> GetRepository();