在模板化类中使用shared_from_this [英] Using shared_from_this in templated classes

查看:148
本文介绍了在模板化类中使用shared_from_this的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个资源管理器,就像《现代C ++设计》一书中提出的Andrei Alexandrescu一样,它遵循基于策略的设计。不过,我遇到了麻烦,因为我的资源管理器需要能够通过 shared_from_this()为托管资源提供对自身的引用。

I have a resource manager that, like Andrei Alexandrescu proposed in the book Modern C++ Design, follows a policy based design. I am having trouble though, because my resource manager needs to be able to provide references to itself to the managed resources by shared_from_this().

我建立了一个重现我的问题的最小示例,结果您可以在此处看到。

I built a minimal example reproducing my problem, which results you can see here.

基本上,我有一些托管资源需要引用其管理器:

Basically I have some managed resource that needs a reference to its manager:

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

还有一个存储和提供资源的经理:

And a manager that stores and provides resources:

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

如您所见,存储本身是基于策略的。虽然经理确实创建了资源,但是该策略可以在存储信息的各种方法之间自由决定(例如,可以选择不存储任何内容,每次都创建新资源)。

As you can see, the storing itself is policy-based. While the manager does create the resources, the policy can freely decide between various approaches of storing the information (it could e.g. choose to not store anything and create new resources every time).

这是存储策略的示例:

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

输出见最小示例

是否不可能在基于策略的设计中使用 std :: enable_shared_from_this shared_from_this()?如果没有,使用它的正确方法是什么?

Is it impossible to use std::enable_shared_from_this and shared_from_this() within policy based design? If not, what is the proper way of using it?

推荐答案

enable_shared_from_this< manager< Policy>> ; 是一个依赖基(这是一个基类,其类型取决于模板参数,在本例中为 Policy ),因此C ++的规则要说没有合格的名字查找不在那儿,您需要说 this-> shared_from_this() std :: enable_shared_from_this< manage< Policy>> :: shared_from_this()从依赖库中查找成员。

enable_shared_from_this<manager<Policy>> is a "dependent base" (it's a base class whose type depends on a template parameter, in this case Policy) so the rules of C++ say that unqualified name lookup doesn't look in there, you need to say this->shared_from_this() or std::enable_shared_from_this<manage<Policy>>::shared_from_this() to find the member from the dependent base.

请参见http://gcc.gnu.org/wiki/VerboseDiagnostics#dependent_base 了解更多详细信息以及指向其他参考文献的链接。

See http://gcc.gnu.org/wiki/VerboseDiagnostics#dependent_base for more detail and links to other references.

要解决第二个错误,您需要将 enable_shared_from_this 设置为 public 基类,否则在启动该类时无法对其进行初始化经理由 shared_ptr 拥有。

To fix the second error you need to make enable_shared_from_this a public base class, or it can't get initialized when the manager is owned by a shared_ptr.

这篇关于在模板化类中使用shared_from_this的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆