objectfactory — фабрика объектов C ++ со встроенным кешем — параметр шаблона shadows

У меня есть класс базы данных, который должен предоставлять метод шаблона для возврата объектов репозитория, представляющих таблицы. Каждый репозиторий должен существовать только один раз. я нашел этот пример, но я хочу иметь встроенный кэш.

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

Реализация GetRepository Метод выглядит так:

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

Я хотел бы назвать это так:

// SampleRepository is derived from RepositoryBase
shared_ptr<SampleRepository> sampleRepo = GetRepository<SampleRepository>();

Когда я компилирую, я получаю ошибку:

error : declaration of 'T' shadows template parameter

Что мне нужно изменить в методе шаблона, чтобы не скрывать какой-либо параметр шаблона?


ОБНОВИТЬ

После предложений NathanOliver метод шаблона выглядит следующим образом:

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]();
}

На этот раз я получаю ошибку:

error : template parameter redefines default argument

Это указывает на nullptr в подписи шаблона.


ОБНОВЛЕНИЕ 2

Я попробовал несколько комбинаций параметров, основанных на ответе, полученном от @NathanOliver. Тем не менее я получаю ошибку:

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>                                                                                                           ^

Для лучшего понимания я также добавил базовый класс хранилища.

class RepositoryBase
{
public:
RepositoryBase(sqlite3* connection);
virtual string GetTableName() = 0;

protected:
sqlite3* _connection;
};

0

Решение

Проблема здесь в том, что

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

недопустимый синтаксис в C ++. Если вы хотите ограничить T быть RepositoryBase или полученный из RepositoryBase то вам нужно сделать это в template<typename T> часть. Что мы делаем, это добавляем проверку типа, который T Если и эта проверка не удалась, компилятор не сгенерирует функцию, которая вызовет ошибку компилятора. Это было бы похоже

template<typename T, typename std::enable_if<std::is_base_of<RepositoryBase, T>::value>::type* = nullptr>
shared_ptr<T> GetRepository();
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]