C++17 是否允许向前声明嵌套类

Will C++17 allow forward declaration of nested classes?

本文关键字:声明 嵌套 是否 C++17      更新时间:2023-10-16

不知道在哪里问(如果这是一个不合适的问题,请随时关闭它),但我在 C++17 个提案中没有特别找到任何关于这方面的内容,在处理嵌套命名空间添加到C++时,这个或这个都没有提到它。

所以目前这是唯一的选择:

class A 
{
public: 
    class B; //forward-declared INSIDE class/namespace
};
class A::B //defined outside
{
};

这在 C++17 中可能吗?

class A::B; //forward declared NESTED outside of parent class/namespace
class C
{
    A::B *b;
};

然后要么这个 (1)(似乎是嵌套名称的提议)

class A::B //definition of A::B without defining A
{
};

或这个 (2)

class A
{
public:
    class A::B
    {
    };
};

或者这个 [3]

class A
{
public:
    class B;
};
class A::B
{
};

我怀疑没有首先定义AA::B定义可能行不通(尽管该提案似乎允许这样做)。

有一个关于这个问题的提案,标题为Forward declarations of nested classes P0289R0。然而,正如您从2016年2月在杰克逊维尔举行的上一次旅行报告:C++标准会议中看到的那样,该提案与鼓励进一步工作的提案有关。我引用委员会的裁决(强调我的):

这将允许像X::A*这样的东西出现在标题中,而没有 要求X的定义也出现在标题中 (XX::A的前瞻性申报就足够了)。EWG发现 用例引人注目,因为目前很多类定义 仅在标头中定义的接口使用 指向该类型的嵌套类的指针或引用。几个细节 仍然需要解决。(例如,如果 X的定义没有出现在任何其他翻译单元(TU)中? 如果X的定义出现在另一个 TU 中,但没有 定义嵌套class A?如果它确实定义了嵌套类会发生什么情况 答,但它是私人的?其中一些或全部的答案可能必须是 "格式不正确,无需诊断",因为诊断错误 这种类型需要大量的链接器支持。

恕我直言,缺乏对类进行前向减速的能力是C++语言定义中的一个主要漏洞,这导致人们使用void*,而前向引用会更安全。

以下是使用命名空间的解决方法:

  1. 扁平化需要预先声明的类结构
  2. 使用命名空间分隔代码
  3. 使用命名空间进行前向减速
namespace ns1 {
namespace ns2 {  
typedef class C * cptr_t; // declare both class and a pointer type
}}
ns1::ns2::C *cp;      // use forward deceleration of the class
ns1::ns2::cptr_t cp;  // use the typedef

此解决方法不能正确解决问题,但在某些情况下可能会有所帮助。