在C ++ 11中,类型说明符包括类说明符和枚举说明符。 (又名类定义和枚举定义)
根据语法/语法 - 类型说明符可以出现在语言的几个地方,但不是所有那些地方都允许使用类说明符和枚举说明符。
例如:
struct C{} c;
// ok: types may be defined in the specifiers of a simple declaration
void f(struct S{});
// error: types may not be defined in parameter types
constexpr auto i = sizeof(enum E{});
// error: types may not be defined in ‘sizeof’ expressions
在标准中,它将类型说明符的这些用法划分为哪些类型可能定义,也可能不定义?例如,哪个类型的规则可能没有在sizeof表达式中定义?
答案 0 :(得分:8)
在C ++标准中找不到它的原因是因为它实际上禁止在C标准的增量中使用。
在C.1.4中我们有以下内容:Change: Types must be declared in declarations, not in expressions In C, a sizeof expression or cast expression may create a new type.
显示有问题的禁令。
这在7.1.6 / 3中明确提到:
至少需要一个不是cv-qualifier的类型说明符 声明,除非它声明构造函数,析构函数或 转换函数.92 type-specifier-seq不应定义类 或者枚举,除非它出现在一个类型的id中 alias-declaration(7.1.3)不是a的声明 模板声明。
其中特别感兴趣的部分是A type-specifier-seq shall not define a class or enumeration unless...
答案 1 :(得分:3)
来自N3797:
8.3.5 / 9不应在返回或参数类型中定义类型。函数定义的参数类型或返回类型 不是一个不完整的类类型(可能是cv-qualified),除非 功能被删除( 8.4.3)或定义嵌套在该类的成员规范中(包括在其中定义的嵌套类中的定义) 班级)。
这阻止在函数声明中定义新类型。
接下来的两个是OP未提及的其他角落案例:
11.3 / 2不得在朋友声明中定义一个班级。
14.1 / 2不应在模板参数声明中定义类型。
最后,该子句在sizeof
和其他地方阻止它:
7.1.6 / 3 type-specifier-seq不应定义类或枚举,除非它出现在类型id中 别名声明(7.1.3),它不是模板声明的声明
请注意,C没有该限制(C.1.4)
此外,在以前版本的C ++标准中,我们有:
5.3.3p5类型不应在sizeof表达式中定义
我在最新的版本标准提案中找不到,并且在N3797下是冗余的,因为sizeof
在语法中定义类型的路由是type-specifier-seq
,并且被7.1.6阻止/ 3:
sizeof(type-id)
- > type-id
- > type-specifer-seq
- > type-specifier
- > class-specifier