§3.1/ 2表示 opaque-enum-declaration 是不定义的声明。然而它占据了记忆中的空间。将它与同样具有大小的定义类进行比较。两者都是标准的完整类型。为什么一个是声明而另一个是定义?
#include <iostream>
enum A : int; // opaque-enum-declaration
class B{}; // a class definition
int main() {
std::cout << sizeof(A) << '\n';
std::cout << sizeof(B) << '\n';
}
输出
4
1
修改
我可以理解下面的opaque-enum-declaration enum A : int;
。
#include <iostream>
enum A : int; // opaque-enum-declaration
int main() {
A a;
std::cout << a << '\n';
}
EDIT1
就变量a
而言,前一个片段和下面的片段之间没有区别。它们都保留变量undefined。因此,很难接受enum : int;
是一个声明而enum A : int {quick, brown, fox};
是一个定义。
#include <iostream>
enum A : int {quick, brown, fox};
int main() {
A a;
std::cout << a << '\n';
}
答案 0 :(得分:2)
大小只是enum
的一个方面。尽管编译器知道大小足以让您在其他声明或定义中使用enum
,但enum
本身仍然未定义,直到您枚举其成员为止。本质上,enum A : int
向编译器承诺两件事 - 即
enum A
,enum A
的所有成员都将拥有适合int
。一旦编译器发现enum A
的定义,它会检查成员是否足够小于声明的大小,并考虑定义enum
。从那时起,提供相同enum A
的另一个定义是错误的。
相比之下,你的class B
已经完全完成了:你告诉编译器class B
将是空的;你不能为它提供一个替代定义,给它一些成员。
编辑:
opaque-enum-declaration枚举A:int;以下是我所能理解的定义。
XYZ
在您的计划中的某个点之后才被视为已定义,之后提供XYZ
的定义构成错误。为此,enum A
在您的计划中仍然未定义,因为您可以在main
之后定义它,如下所示:
#include <iostream>
enum A : int; // opaque-enum-declaration
int main() {
A a;
std::cout << a << '\n';
}
// This is allowed
enum A : int {quick, brown, fox};
顺便说一句,这并不妨碍您的程序成功编译,因为在C ++中 undefined 不等同于不可用。
答案 1 :(得分:2)
类型为完整,但在 opaque-enum-declaration 之后
7.2 [dlc.enum] / 3
opaque-enum-declaration是枚举的重新声明 在当前范围或新枚举的声明中。 [注意:安 由opaque-enum-declaration声明的枚举已修复 基础类型,是一个完整的类型。(枚举器列表可以是 在后来的重新声明中提供了一个enumspecifier。 - 注意事项] A. 范围的枚举不得在以后重新声明为无范围或具有 不同的基础类型。不受限制的查点不得晚于 重新声明为范围,每个重新声明应包括枚举 指定与原始声明中相同的基础类型。
上面的完整类型表示只要看到 opaque-enum-declaration ,就可以使用sizeof
成为你的顾虑。它仍然不是定义,因为定义需要指定类型的所有方面, opaque-enum-declaration 不会。
如果要将其与类定义进行比较, opaque-enum-declaration 将等同于包含所有非静态数据成员的类[half]定义和表示是否的属性将存在虚函数,但不声明任何成员函数。对象的大小很清楚,但不是如何使用它。
答案 2 :(得分:0)
本声明
enum A : int;
是一份声明。这意味着声明名称A表示某种范围的枚举类型。它不占用记忆。
本声明
class B{};
也是一个类声明。它也被称为类定义,因为它定义了类的结构。但是这个声明并没有占用记忆。枚举或类类型的对象占用内存。这些陈述
std::cout << sizeof(A) << '\n';
std::cout << sizeof(B) << '\n';
显示如果某个对象被定义为具有这些类型之一,则可以占用多少内存。
考虑以下代码
#include <iostream>
int main()
{
std::cout << sizeof( int ) << std::endl;
}
此代码输出int类型的对象的大小。但是程序中没有定义任何对象。
将上面的代码与以下代码进行比较
#include <iostream>
int main()
{
int x;
std::cout << sizeof( x ) << std::endl;
}
在此程序中定义了x类型的对象。它确实占据了记忆。 int只是一个简单的类型说明符。代码中的A和B的方式与类型说明符相同。类型说明符只是一些描述。他们没有占据记忆。