为什么我不能用 typedef 完成类型?
Why can't I complete the type with the typedef?
给定翻译单元 A 中的不完整类型:
struct Incomplete;
Incomplete* create_incomplete();
void destroy_incomplete(Incomplete*);
为什么我不能通过 typedef
在另一个翻译单元中使用它?
例如在翻译单元 B 中:
struct Unrelated
{
int x;
int y;
};
typedef Unrelated Incomplete;
Incomplete* create_incomplete()
{
return new Incomplete();
}
void destroy_incomplete(Incomplete* arg)
{
delete arg;
}
您无法完成在不同翻译单元中声明的内容。要么你 #include
你的第一个文件在第二个文件中,在这种情况下你在一个翻译单元中发生了所有事情,或者,如果你不 #include
它,你只有一个 typedef
单元 B 中没有不完整的类型,单元 A 中没有不完整的类型(你永远不会完成,因为你不必完成)。
而且你无法在一个单元中完成 class 和 typedef
,因为:
3.9.5. A class that has been declared but not defined, or an array of unknown
size or of incomplete element type, is an incompletely-defined object
type. Incompletely-defined object types and the void types are
incomplete types.
3.9.2. A declaration is a definition unless <…> it is a typedef
declaration, <…>.
(N3337;部分重点是我加的。)
因此,您无法使用 typedef
来完成 class 类型,因为 class 类型只能由 definition[=30= 完成] 和 typedef
声明不是定义。
Incomplete
是一种类型,由您的声明引入,您不能使用相同名称的 typedef,引用另一种类型。
您的 struct Incomplete;
是前向 class 声明,它将 class 名称插入全局范围(并引入了一个新的但不完整的类型)。
§9/2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen.
§9.1/2
A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name.
为了在需要完整类型的地方使用该名称,必须对其进行定义。
§3.2/4
Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.
A class 是使用 class 说明符定义的。
§9/2
A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined.
你的 typedef 是一个声明,并没有定义 class.
§7.1.3/1
Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming fundamental (3.9.1) or compound (3.9.2) types.
§3.1/2
A declaration is a definition unless [...] it is a typedef declaration [...].
而同一范围/声明区域中的声明需要引用同一实体。
§3.3.1/4
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name
- they shall all refer to the same entity, or all refer to functions and function templates; [ ... ]
您的 typedef 声明 Incomplete
引用 Unrelated
而 struct Incomplete;
声明类型 Incomplete
.
§7.1.3/6
In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.
C++11
给定翻译单元 A 中的不完整类型:
struct Incomplete;
Incomplete* create_incomplete();
void destroy_incomplete(Incomplete*);
为什么我不能通过 typedef
在另一个翻译单元中使用它?
例如在翻译单元 B 中:
struct Unrelated
{
int x;
int y;
};
typedef Unrelated Incomplete;
Incomplete* create_incomplete()
{
return new Incomplete();
}
void destroy_incomplete(Incomplete* arg)
{
delete arg;
}
您无法完成在不同翻译单元中声明的内容。要么你 #include
你的第一个文件在第二个文件中,在这种情况下你在一个翻译单元中发生了所有事情,或者,如果你不 #include
它,你只有一个 typedef
单元 B 中没有不完整的类型,单元 A 中没有不完整的类型(你永远不会完成,因为你不必完成)。
而且你无法在一个单元中完成 class 和 typedef
,因为:
3.9.5. A class that has been declared but not defined, or an array of unknown size or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and the void types are incomplete types.
3.9.2. A declaration is a definition unless <…> it is a
typedef
declaration, <…>.
(N3337;部分重点是我加的。)
因此,您无法使用 typedef
来完成 class 类型,因为 class 类型只能由 definition[=30= 完成] 和 typedef
声明不是定义。
Incomplete
是一种类型,由您的声明引入,您不能使用相同名称的 typedef,引用另一种类型。
您的 struct Incomplete;
是前向 class 声明,它将 class 名称插入全局范围(并引入了一个新的但不完整的类型)。
§9/2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen.
§9.1/2
A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name.
为了在需要完整类型的地方使用该名称,必须对其进行定义。
§3.2/4
Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.
A class 是使用 class 说明符定义的。
§9/2
A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined.
你的 typedef 是一个声明,并没有定义 class.
§7.1.3/1
Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming fundamental (3.9.1) or compound (3.9.2) types.
§3.1/2
A declaration is a definition unless [...] it is a typedef declaration [...].
而同一范围/声明区域中的声明需要引用同一实体。
§3.3.1/4
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name
- they shall all refer to the same entity, or all refer to functions and function templates; [ ... ]
您的 typedef 声明 Incomplete
引用 Unrelated
而 struct Incomplete;
声明类型 Incomplete
.
§7.1.3/6
In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.
C++11