具有循环依赖性的CRTP

时间:2015-05-09 13:38:05

标签: c++ c++11 crtp

我有一个操作层次结构和(共享)信息类,直观地看起来似乎不需要运行时多态性,但是我找不到没有它的解决方案。

为了这个问题,假设有一个2级层次结构。存在基本操作和派生操作。来自层次结构的同一级别的对象可能需要在它们之间共享信息(意味着基本操作对象需要共享基本信息,派生操作对象需要共享派生信息,但基本操作对象永远不需要共享派生信息或副本反之亦然)。

所以它就像这样开始:

// Shared between base operation objects
class base_info
{

};

// Shared between derived operation objects
class derived_info :
    public base_info
{

};

鉴于没有关于哪些操作对象共享哪些信息对象的运行时问题,还有以下内容:

template<class Info>
class base_op
{
    std::shared_ptr<Info> m_info; 
};

class derived_op :
    public base_op<derived_info>
{

};

其余代码总是使用base_op实例化base_information,因此到此为止不需要运行时多态性。

现在,在某些时候,共享信息对象可以决定是否需要生成新操作。如上所示,操作对象需要共享信息对象的共享指针。所以信息层次结构改变为:

// Shared between base operation objects
class base_info :
   private std::enable_shared_from_this<base_info>
{
    void do_something_spawning_new_ops();
};

...

现在的问题是如何实施do_something_spawning_new_ops。对于运行时多态性,它并不困难:

class base_info :
   private std::enable_shared_from_this<base_info>
{
    void do_something_spawning_new_ops()
    {
        // Need a new op.
        get_op_shared_ptr();
    }

    virtual std::shared_ptr<base_op> get_op_shared_ptr()
    {
        // use shared_from_this, create a base_op object using it.
    }
};

class derived_info :
    public base_info
{
    virtual std::shared_ptr<base_op> get_op_shared_ptr()
    {
        // use shared_from_this + std::*_pointer_cast, 
        //    create a derived_op object
    }    
};

但重点是避免运行时多态性,因为通过设计,一切都可以在实例化时知道。所以回到帖子的开头,有这样的事情会很好:

template<class Op>
class base_info
{

};

class derived_info :
    public base_info<derived_op>
{

};

使用CRTP类型的东西(尽管没有派生),其中op表示它包含创建此类型对象的信息。但这现在导致base_op实例化的循环问题。它需要通过某种信息类型来实例化,这种信息类型本身就是由它自己的类型等实例化的。我不知道如何制动这种类型循环。

修改

根据Panta rhei的建议,here是我瞄准的代码。

1 个答案:

答案 0 :(得分:1)

我仍然不太确定你想要实现什么,但是你需要做的就是在编译代码时在base_info类模板中添加一个类型参数,当你在main中实例化它时。

File Transfer