问题
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