У меня есть менеджер ресурсов, который, как предложил Андрей Александреску в книге Modern C++ Design, следует за политическим дизайном. У меня проблемы, потому что мой менеджер ресурсов должен иметь возможность предоставлять ссылки на себя на управляемые ресурсы на shared_from_this()
.Использование shared_from_this в шаблонных классах
Я построил минимальный пример, воспроизводящий мою проблему, в результате которой вы можете увидеть here.
В принципе у меня есть некоторые управляемый ресурс, который нуждается в ссылку на его менеджер:
template <typename T>
class managed_resource
{
typedef std::shared_ptr<manager<T>> manager_ptr;
public:
managed_resource(manager_ptr const & parent)
: parent_(parent)
{
}
/* ... */
private:
manager_ptr parent_;
};
И менеджер, который хранит и предоставляет ресурсы:
template <typename Policy>
class manager
: Policy
, std::enable_shared_from_this<manager<Policy>>
{
typedef managed_resource<Policy> resource;
typedef std::shared_ptr<resource> resource_ptr;
public:
resource_ptr get_resource(std::string const & name)
{
Policy & p = *this;
if(p.find(name))
{
return p.get(name);
}
resource_ptr res = std::make_shared<resource>(shared_from_this());
p.store(name, res);
return res;
}
};
Как вы можете видеть, хранить себя в на основе политик. В то время как менеджер создает ресурсы, политика может свободно выбирать между различными подходами к хранению информации (она может, например, выбирать, чтобы ничего не хранить и создавать новые ресурсы каждый раз).
Это пример политики хранения:
class map_policy
{
typedef std::shared_ptr<managed_resource<map_policy>> resource_ptr;
typedef std::map<std::string, resource_ptr> resources;
public:
bool find(std::string const & name)
{
resources::iterator res_it = resources_.find(name);
return res_it != resources_.end();
}
resource_ptr get(std::string const & name)
{
resources::iterator res_it = resources_.find(name);
return res_it->second;
}
void store(std::string const & name, resource_ptr const & res)
{
resources_[name] = res;
}
private:
resources resources_;
};
Но я получаю ошибку компиляции:
error: there are no arguments to ‘shared_from_this’ that depend
on a template parameter, so a declaration of
‘shared_from_this’ must be available
error: ‘std::enable_shared_from_this<manager<map_policy> >’ is
an inaccessible base of ‘manager<map_policy>’
Для выхода полной компиляции см minimal example.
Невозможно использовать std::enable_shared_from_this
и shared_from_this()
в рамках основанного на политике дизайна? Если нет, каков его правильный способ?
manager_ptr const & parent? –