c++ - 具有循环依赖性的 CRTP

标签 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_information 实例化 base_op,因此到这里为止不需要运行时多态性。

现在,在某些时候,共享信息对象可以决定它们需要产生新的操作。如上所示,操作对象需要指向共享信息对象的共享指针。所以信息层次结构变成了这样:

// 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是我的目标代码。

最佳答案

我仍然不太确定您要实现的目标,但要使您的代码编译,您需要做的就是在 main 中实例化时在 base_info 类模板中添加一个类型参数。

int main()
{
    derived_op d;
    base_op<base_info<derived_info> > b;
}

关于c++ - 具有循环依赖性的 CRTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30140587/

相关文章:

c++ - 代码未添加最后一个默认值

c# - 加快构建时间的方法? (C#/非托管 C++)

c++ - 在函数调用中,为什么 nullptr 不匹配指向模板对象的指针?

c++ - 声明一个与给定模板参数的函数具有相同签名的函数

c++ - Constexpr CRTP析构函数

c++ - 每个花哨的指针都应该是一个迭代器吗?

c++ - 如何决定在何处处理异常 - 在抛出的函数范围内还是在全局范围内?

c++ - 新别墅ACM解决攻略

c++ - 如果我们使用参数构造函数,我们是否需要在 C++ 中提供默认构造函数?

具有两个运算符的 C++11 歧义错误(一个左值第二个右值)