c++ 在类名的声明和定义中使用不同的类键法律的吗?

5vf7fwbs  于 2022-12-27  发布在  其他
关注(0)|答案(1)|浏览(136)

标准(C++20)是否明确或隐含地允许在(forward-)声明一个 * class-name * 时使用一个与定义它时不同的 * class-key ?对于这个问题, class-key * 应限制为classstruct,不包括union
换句话说,这是否合法:

struct C;
class C{};
class S;
struct S{};

答案应该明确引用C20标准(或合适的草案)。
我在整个class(https://eel.is/c
draft/class)部分中找不到任何内容。
我能找到的唯一指示是在[decl.type.elab.6]中,其中第一条指出:
出现在详细类型说明符中的class-key或enum关键字应与详细类型说明符中的名称所引用的声明在种类上一致。
但对我来说,不清楚 * kind * 在这个上下文中是什么意思。我假设enumstruct是不同的种类,但structclass是不同的种类吗?我不知道。无论如何,在一些关于朋友的不相关的观点之后,它继续说:
因此,在任何详细的类型说明符中,enum关键字应该用于引用枚举([dcl. enum]),联合类键应该用于引用联合([class. union]),并且 * 类或结构类键应该用于引用非联合类 *([class. pre])。
(emph增加)
这听起来好像structclass可以互换,但我不确定。
根据代码资源管理器,它似乎是generally accepted by compilers

非重复

j1dl9f46

j1dl9f461#

标准在9.2.8.3.3中对此进行了解释,并在示例中进行了澄清,正如Peter在对您的问题的评论中所指出的:
[...]classstructclass-key 应用于引用非联合类[...]

struct S { } s;
class S* p = &s;    // OK

编译器同意,这可以从生成的警告叮当声中看出:
警告:“C”在此处定义为结构,但以前声明为类;这是有效的,但在Microsoft C++ ABI [-Wmismatched-tags]下可能会导致链接器错误
GCC有一个常见问题条目:
因为这不是一个bug,所以这个警告只是噪音。这是一个愚蠢的警告,只存在于MS编译器有一个bug,在损坏的名称中以不同的方式处理结构体和类。GCC(和Clang)正确地实现了C++标准,该标准说这无关紧要。

相关问题