我有很多情况需要相互引用嵌套类,例如
class C1;
class C2;
// class C2::S; // not allowed by the standard
template <class T> class R
{
T* t = nullptr; // The only use of T as a data member is a T*
};
class C1
{
public:
class S
{
public:
R <C2::S> r; // Fails to compile because C2 is an incomplete type
};
};
class C2
{
public:
class S
{
public:
R <C1::S> r;
};
};
这会失败,因为 C2 不完整且在使用它的位置,因此编译器不知道 C2::S。
问题分为两部分:
有一些“明显”的解决方案,但我希望不必使用它们:
我期望能够使用虚拟类代替 C2::S,然后在使用它之前将其映射到 C2::S,但看来您无法声明一个类,然后用“using”重新定义它,例如以下不起作用:
class Z; // Z first defined as a class
class C1
{
public:
class S
{
public:
R<Z> r;
};
};
class C2
{...}
using Z = C2::S; // Redefinition error (defining Z as a typedef vs. a class)
我也尝试过使用模板,例如
template <class T> class TC1
{
public:
class S
{
public:
R <typename T::S> r;
};
};
template <class T> class TC2
{
public:
class S
{
public:
R <typename T::S> r;
};
};
using C1 = TC1 <TC2 <C1>>; // Error: C1 undeclared (or not in scope)
关于标准的补充,我意识到允许使用不完整的类型永远是不可接受的,因为这会导致很多复杂性,例如指定可以使用和不可以使用的内容,或者尝试定义同一类的不同部分定义版本何时兼容或不兼容。
我没有主意了。有什么建议吗?
这不是人们希望自己能够写作的常见情况
class A::B;
而不是定义
A
:您只想让嵌套类相互引用。这意味着普通的前向声明有效:
class C1
{
public:
class S;
};
class C2
{
public:
class S
{
public:
R <C1::S> r;
};
};
class C1::S
{
public:
R <C2::S> r;
};
显然这取决于
R
不需要其模板参数是一个完整的类型。