C++ 中相互引用嵌套类

问题描述 投票:0回答:1

我有很多情况需要相互引用嵌套类,例如

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。

问题分为两部分:

  1. 有没有办法让这个在 C++23 中工作?
  2. 如果没有,是否有或曾经有过向 C++ 委员会提出的任何有帮助的提案?

有一些“明显”的解决方案,但我希望不必使用它们:

  • 扁平化结构,避免嵌套。我的实际示例要复杂得多,这会使代码不可读。
  • 使用 void*,然后根据需要进行转换。

我期望能够使用虚拟类代替 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)

关于标准的补充,我意识到允许使用不完整的类型永远是不可接受的,因为这会导致很多复杂性,例如指定可以使用和不可以使用的内容,或者尝试定义同一类的不同部分定义版本何时兼容或不兼容。

我没有主意了。有什么建议吗?

c++ inner-classes incomplete-type
1个回答
0
投票

这不是人们希望自己能够写作的常见情况

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
不需要其模板参数是一个完整的类型。

© www.soinside.com 2019 - 2024. All rights reserved.