【问题标题】:Inheriting from a template with a member class of the inheriting class as a template parameter以继承类的成员类作为模板参数从模板继承
【发布时间】:2018-07-31 17:38:34
【问题描述】:

我想从类模板继承,但是将继承类的成员类作为模板参数传递给基类。这甚至可能吗?这是一个最小的例子。

template<typename T>
class Base { /* stuff involving T */ };

template <typename U>
class Derived : Base<typename Derived<U>::Member> {
public:
    class Member { /* stuff involving U */};
    /* stuff involving Member, Base<Member> and U */
};

在我尝试创建Derived 的实例(例如Derived&lt;int&gt;)之前编译良好,此时 g++ (7.2.0) 告诉我我正在使用不完整的类型。

In instantiation of ‘class Derived<int>’:
 error: invalid use of incomplete type ‘class Derived<int>’
 class Derived : Base<typename Derived<U>::Member> {
       ^~~~~~~

我可以看出问题所在:Base 的实例化需要 Derived::Member 的知识,这尚未定义,但有什么办法可以解决这个问题?

作为替代方案,我可以在Derived 之外拥有Member,但是我失去了将其作为成员类的优势(访问Derived 的私有和受保护成员,Member 的封装等...)。我也考虑过让Member 成为Base 的成员,但从逻辑上讲,Member 的内容特定于Derived,不属于更一般的Base

【问题讨论】:

  • Member 的定义是什么? T 如何在 Base 中使用(是否有一些 T 值)?
  • 是的,需要有一个 T 值并调用 T 的成员函数。

标签: c++ templates inheritance


【解决方案1】:

经过一番调查,我认为这是不可能的。最接近有效的是此处描述的奇怪重复模板模式 (CRTP):What is the curiously recurring template pattern (CRTP)?

正如这里Why this CRTP does not compile? 和其他地方所指出的,DerivedBase 的模板实例化时是一个不完整的类型。因此Member不知道存在,导致错误。

我找到的最接近解决方案的方法是将 Member 的功能移动到一个单独的非成员类 (NonMemebr) 并让 Member 继承自该类。这样Base&lt;NonMember&gt; 之外的每个人都不需要知道NonMember 的存在。

template<typename T>
class Base { /* Instance of T. */ };

namespace detail {
    class NotMember { /* Functionality I'd like to have in Member. */ };
}

template <typename U>
class Derived : Base<detail::NotMember> {
public:
    class Member : public detail::NotMember { /* Appropriate constructors. */ };
    /* Stuff involving U, Base<NotMember> and Member. */
};

这可能不是最漂亮的,但它确实可以满足我的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 2014-07-15
    • 2018-12-03
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多