继承具有嵌套类的模板类

时间:2018-07-26 23:47:20

标签: c++ templates inheritance inner-classes

我想创建一个从模板类A继承的类B。我希望B的嵌套类E作为此继承中的模板参数。更加直观:

template <class T>
class A {
}

class B : public A<B::E> {
    class E {
        int x;
    }
}

class C : public A<C::E> {
    class E {
        int x;
        int y;
    }
}

我认为问题在于编译器在处理B的声明时不知道类B将具有嵌套类E,因为我遇到了错误:

  

在“ B”中没有名为“ E”的成员

我已经看到了这个similar question,但是我想确认在放弃这种方法之前,没有直接解决此冲突的方法。

谢谢!

3 个答案:

答案 0 :(得分:3)

我能想到的最接近的方法是使用基类。

template <class T>
class A {
};

class B; // forward declaration of ::B
namespace detail { 
class B { 
    friend class ::B;
    class E {
        int x;
    };
};
} /* namespace detail */

class B : public A<detail::B::E> {
};

答案 1 :(得分:3)

我认为这不能直接完成。

一种显而易见的方法是,在其他命名空间中定义B::EC::E(至少将它们保留在全局命名空间之外),然后在“父”类中使用它们:

template <class T>
class A { /* ... */ };

namespace B_detail {
    class E { /* … */ };
}

class B : public A<B_detail::E> { /* ... */ };

namespace C_detail {
    class E { /* ... */ };
}

class C : public A<C_detail::E> { /* ... */ };

视情况而定,您很有可能需要/想要声明*_detail::Efriend的B / C。

答案 2 :(得分:0)

正如其他人所说,您不能对嵌套类进行前向声明。

因此,您可以使用将您的 nested 类放在namespace中。或者,您可以只删除任何嵌套,然后必须提供不同的名称。

这里是一个演示两种方法的示例。而且,如果您不需要前向声明,则代码可能会更简单。

#include <memory>

template <class T>
class A {
public:
    A();

    // Demonstrate a possible way that T could be used.
    std::unique_ptr<T> t;
};

template <class T>
A<T>::A() : t(std::make_unique<T>())
{
}

// Using a forward declared (top level) class...
class B : public A<class BE> {
};

class BE {
public:
    int x;
};

// Using a forward declared class inside a namespace...
namespace C_details
{
    class E;
}

class C : public A<C_details::E> {
};

namespace C_details
{
    class E {
    public:
        int x;
        int y;
    };
}


int main()
{
    B b;
    b.t->x = 3;

    C c;
    c.t->y = 4;

    return 0;
}