从模板继承,并将继承类的成员类作为模板参数

时间:2018-07-31 17:38:34

标签: c++ templates inheritance

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

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<int>)的实例之前,该编译很好,此时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的知识,但尚未定义,但是有什么解决办法吗?

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

1 个答案:

答案 0 :(得分:0)

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

Why this CRTP does not compile?和其他地方所述,Derived在模板Base实例化时是不完整的类型。因此,Member不存在,从而导致错误。

我找到的最接近解决方案的方法是将Member的功能移到一个单独的非成员类(NonMemebr)中,并让Member从中继承。这样,Base<NonMember>以外的每个人都不需要知道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. */
};

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