我想创建一个从模板类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,但是我想确认在放弃这种方法之前,没有直接解决此冲突的方法。
谢谢!
答案 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::E
和C::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::E
为friend
的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;
}