Inherit template class with nested class

给你一囗甜甜゛ 提交于 2021-01-27 14:26:43

问题


I want to create a class B that inherits from template class A. And I want the B's nested class E to be the template parameter in this inheritance. More visually:

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;
    }
}

I think the problem is that the compiler doesn't know that the class B will have a nested class E by the time it's processing the declaration of B, since I'm getting the error:

no member named 'E' in 'B'

I've seen this similar question, but I would like to confirm that there's no direct solution to this conflict before giving up with this approach.

Thanks!


回答1:


I don't think it can be done directly.

One obvious approach would be something like defining B::E and C::E in some other namespace (to at least keep them out of the global namespace), then use them inside of the "parent" classes:

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> { /* ... */ };

Depending upon the situation, there's a decent chance you'd also need/want to declare *_detail::E a friend of B/C.




回答2:


The closest thing I can think of is to use a base class.

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> {
};



回答3:


As other have said, you cannot do a forward declaration of a nested class.

So you can use put your nested class inside a namespace instead. Or alternatively, you could just remove any nesting but then you would have to provide distinct names.

Here is one example that demonstrate both ways. And if you don't need forward declaration the code could be even a bit simpler.

#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;
}


来源:https://stackoverflow.com/questions/51548938/inherit-template-class-with-nested-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!