为什么嵌套类不能有一个类型为封闭类的成员?
Why a nested class can't have a member the type of which is the one of the enclosing class?
类C
的方法之一需要返回一个包含一对整数和C
的新实例的struct
。它可能看起来很尴尬,但考虑到整体设计,这很有意义(想想一个Waveform
类将自身的一个范围作为副本返回,并指示范围的开始和结束位置)。
问题是这似乎是不允许的。我可以重新设计我的类以规避这个问题,但你能解释一下为什么从编译器的角度来看,这不能做到
吗struct S {
struct S2 {
S s;
};
};
因为S
是一个不完整的类型(这是编译器错误),相反,这很好
struct C {
struct C1 {
C makeC() { return C(); }
};
};
实质性差异在哪里?
在你尝试定义S::S2
时,类型 S
仍然是一个不完整的类型,因为它的定义尚未完成。并且类数据成员必须具有完整的类型。
您可以像这样轻松修复它:
struct S
{
struct S2; // declare only, don't define
// ...
};
struct S::S2
{
S s; // now "S" is a complete type
};
它本质上是一个C++的设计决策,在定义结束之前不考虑一个类型是完整的。这可以防止许多病理情况,如以下示例所示:
struct X
{
struct Y { X a; };
int b[sizeof(Y)]; // "sizeof" requires a complete type
};
当你想要定义一个类时,你需要一个所有嵌入(非引用和非指针)成员的完整定义。定义类时,未完全定义类。也就是说,在类定义中,定义的类只是声明的,而不是定义的。
也就是说,您仍然可以在嵌套类中拥有类的成员。你只需要在定义外部类之后定义嵌套类:
struct S {
struct S2;
};
struct S::S2 {
S s;
};
由于S
完全由第一个右大括号定义,因此在此点之后可以将其用作嵌入构件。
中定义成员函数时,定义将被解析为紧跟在最接近的命名空间级别的类定义之后。也就是说,成员函数定义知道完全定义的类。这同样不适用于嵌套类。
为什么,但我可以推测这个反例:
struct S {
struct S2 {
S s;
};
S2 s2;
};
在这种情况下,尝试在扫描S
并确定其大小之前S2
将失败。我怀疑递归可能会给编译器带来困难,而这种困难通常是标准中规则的原因。
也就是说,我认为您的解决方案不太适合您所描述的问题。我会在S
上制作S2
模板,无论如何都不会嵌套。然后,我将能够对模板参数使用引用S&
,而不是S
本身。因此,范围将由两个整数和对原始数组对象的引用表示。从此范围制作新副本将是一个单独的操作。
编译器无法计算封闭类的大小。
不过你可以写S* s;
。
这个答案侧重于你的两个例子之间的区别,因为其他答案已经解释了为什么第一个不起作用。
简而言之,您的第一个示例以需要S
才能完成的方式使用S
中的S
。
第二个示例要求C
在编译函数体后立即完成。您的代码等效于
struct C {
struct C1 {
C makeC();
};
};
inline C C::C1::makeC() {
return C();
}
这意味着,编译器会自动"推迟"函数体。对于函数声明,编译器只需要知道C
是一种类型,但如果C
不完整,它就可以工作,直到那时。编译函数定义时,类型C
现已完成。
- 根据模板类型选择类模板的成员类型?
- 函数模板签名中忽略的成员类型def 的访问说明符
- 在C++如何从数组中提取成员并返回成员类型的数组?
- C++从成员类型中扣除类型的功能模板?
- 无法初始化以 std::byte 作为成员类型的位字段
- 构造函数可以更改默认成员类型吗?
- 使用相同方法但不同成员类型构建类的最佳方法
- 允许通过指向方法的成员参数的指针来推断模板参数所指向的成员类型
- 使用 std::条件根据模板参数选择成员类型
- CRTP:如何推断要用作返回类型的成员类型?
- 对成员类型的成员方法使用 std::result_of<>
- C :可以从类及其受保护的成员类型继承可以继承吗?
- 如何在不指定不必要的模板参数的情况下使用模板类的成员类型
- 基类数据成员类型取决于派生类
- C 多态性:允许模棱两可的成员类型
- 使用使用成员类型别名的构造函数来推论类模板参数
- 获取与在模板参数中传递的函数成员类型相同的类
- 如果静态成员未初始化并且成员类型是类本身,该怎么办?
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- 将联合强制转换为其成员类型之一