Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11类型说明符使用中允许的类型定义的标准参考?_C++_C++11_Language Lawyer_Specifier_Type Declaration - Fatal编程技术网

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

C++ C++;11类型说明符使用中允许的类型定义的标准参考?,c++,c++11,language-lawyer,specifier,type-declaration,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 ty

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

< P>在C++标准中找不到的原因是因为它实际上是在C标准的三角洲中禁止的。 在C.1.4中,我们有以下内容:
Change:类型必须在声明中声明,而不是在C中的表达式中声明,sizeof表达式或cast表达式可能会创建一个新类型。
这表明了有疑问的禁止

这在7.1.6/3中明确指出:

中至少需要一个不是cv限定符的类型说明符 除非声明构造函数、析构函数或 转换功能。92类型说明符seq不得定义类别 或枚举,除非它出现在 别名声明(7.1.3),该声明不是 模板声明

如果特别感兴趣的部分是
类型说明符seq不应定义类别或枚举,除非N3797中的…

8.3.5/9返回或参数类型中不得定义类型。参数类型或函数定义的返回类型应为 除非 函数被删除( 8.4.3)或定义嵌套在该类别的成员规范中(包括定义在 (课堂上)

这将阻止在函数声明中定义新类型

接下来的两个是OP未提及的其他角落案例:

11.3/2类不得在友元声明中定义

14.1/2模板参数声明中不得定义类型

最后,此子句在
sizeof
和其他地方阻止它:

7.1.6/3类型说明符seq不得定义类别或枚举,除非其出现在 不是模板声明声明的别名声明(7.1.3)

注意,C没有该限制(C.1.4)

另外,在C++标准的前一版本中,我们有:

5.3.3p5类型不得在sizeof表达式中定义

我在最新版本的标准提案中找不到,在N3797下是多余的,因为语法中定义类型的路径是通过
类型说明符seq
,并被7.1.6/3阻止:


sizeof(type id)
->
type id
->
类型说明符seq
->
类型说明符
->
类说明符

对于
sizeof
来说,至少可以从5.3/1中指定的
一元表达式
语法中推断出这一点,但从粗略的观察,这一点并不明显(由于递归定义)。+1,问得好。但是阅读关于这个特定主题的标准会让人迷失方向,到处都是引用。顺便说一句,你能举个例子说明你真正需要这些东西吗?瞧,不总是可以将定义分成两部分吗?@MarkB:
sizeof(type id)
->
类型id
->
类型说明符seq
->
类型说明符
->
类说明符
。顺便说一句,附录A是语法摘要。从语法上讲,它是允许的,所以一定有一些文本在某个地方说您不能在那里定义类型。啊,如果只有Clang 4.X在编译器中显示标准引用就好了错误;-)@TemplateRex:实际上这不是个坏主意。但是需要做很多匹配工作。
sizeof
始终是一个表达式,因此不应在sizeof表达式中定义
类型
对于必须在声明中声明的
类型是多余的,不在表达式中。
遗憾的是,该部分是信息性的而不是规范性的——它旨在告诉您文档的其余部分是什么,它不应该定义新的信息。我试图找到它的
规范性
文本,但失败了。@hvd:不,它是decl说明符seq,decl说明符seq永远不是类型说明符seq,尽管decl说明符有时是类型说明符。@AndrewTomazos啊,谢谢,它是类型说明符(decl说明符可以是类型说明符),但不是类型说明符seq。有趣的是,这似乎允许在for范围声明中进行类型定义:
for(struct S2{}S2:s){}
,GCC使用
-std=c++11-pedantic
接受该声明,而不进行任何诊断,但对于该声明,clang给出了一个明确的“错误:类型可能无法在for范围声明中定义”@hvd:除非有其他文本,Clang是错误的,它是decl说明符seq,既不是返回类型也不是参数类型。