C ++ 11标准参考使用类型说明符中允许的类型定义?

时间:2014-01-07 19:34:29

标签: c++ c++11 language-lawyer specifier type-declaration

在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表达式中定义?

2 个答案:

答案 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