我想知道C++是如何使用它的const关键字的。
我有下面的函数定义。这一点看起来很疯狂,但工作起来很好。
const int const * const Get(){ return new int(1); } const我知道const的每个位置意味着什么,这个问题不是关于const关键字的位置的意义。
我对const关键字的使用感到非常困惑,因为您可以复制它们。
const int const const * const Get(){ return new int(1); } const
// or even
const const int const const * const const Get(){ return new int(1); } const const
// or even yet
const const const int const const const * const const const Get(){ return new int(1); } const const const为什么语言允许你这样做呢?
编辑:此代码可以在Visual Studio2013中编译,Visual C++编译器。我不确定编译器的实际名称。
EDIT2:所以答案是这违反了标准。该代码仅在不使用/Za选项的情况下编译。
我投票决定结束这个问题。
发布于 2015-06-12 16:42:10
在标准中不允许在同一类型说明符序列中显式重复const。
dcl.type/2 (强调我的)
作为一般规则,在声明的完整decl说明符seq或类型说明符seq或尾随类型说明符seq中最多允许一个类型说明符。
..。
-常量可以与除其自身以外的任何类型说明符组合。
人们可能会认为这是从以下引用中允许的(由@davidhigh找到):
dcl.type.cv/1
有两个cv限定符,const和volatile。每个cv限定符在一个cv限定符seq中最多只能出现一次。如果cv限定符出现在decl-specifier-seq中,则声明的init-声明符列表不能为空。注意: 3.9.3和8.3.5描述了cv限定符如何影响对象和函数类型。-结束语冗余的简历资格被忽略。注意:例如,这些可以通过typedefs引入。-结束注释
然而,这条规则允许通过在模板或typedef中进行替换而产生的const复制,而不是程序员显式键入的复制。
举一个你的例子:
const const int const const * const const Get(){ return new int(1); } const const前四个const都适用于int,违反了上面发布的规则。
接下来的两个const应用于指针,并且根据相同的规则是无效的。
最后两个const甚至不是Get声明的一部分。它们将应用于解析器接下来找到的任何内容,由于与上面相同的规则或其他C++语法规则而变得无效。
VS2013可能会使用语言扩展来编译这样的代码,但这不是标准行为。gcc 5.1.0和clang 3.5.1都会拒绝编译您的代码,并且都会提供合理的诊断。
发布于 2015-06-12 16:42:47
回复
“为什么语言允许这样做?”
不是的,提供的代码是而不是真正的代码。例如。
const int const * const Get(){ return new int(1); } const(第一个示例)不会使用任何符合标准的编译器进行编译,原因有两个:
the multiple const at the multipleconst at the int) are not
constat the end is a syntax (对于int)is a语法错误。第一点的标准: C++11§7.1.6/2,
“
const可以与除其自身以外的任何类型说明符组合。
发布于 2015-06-12 16:35:00
为什么?因为标准是这么说的。以下是dcl.type.cv的摘录,它确切地说明了这一点(强调我的):
有两个cv限定符,const和volatile。每个cv限定符在一个cv限定符seq中最多只能出现一次。如果cv限定符出现在decl-specifier-seq中,则声明的init-声明符列表不能为空。注意: 3.9.3和8.3.5描述了cv限定符如何影响对象和函数类型。- end备注多余的cv-被忽略。typedefs备注:例如,可以通过typedefs引入。-结束注释
例如,这在模板中是有意义的。如果将模板参数推导为const,则很容易在此处添加另一个常量。
编辑:正如多次重复提到的,我上面的回答是误导性的,因为它不符合这里的条件。这与dcl.type中的规则相反,该规则明确禁止显式类型的const限定符(参见@TartanLlama在他的答案中的精细注释)。
EDIT 2:规则的应用似乎每个人都同意以下状态:首先,不允许冗余的const,如果它们仍然应该在某个地方发生,则忽略它们。
然而,这需要标准引号的优先级。
如果没有,还可以考虑这样的顺序:首先删除冗余的const,然后才应用不允许多个const的规则(当然,这会使后一个规则本身变得冗余)。
显然,在这种情况下,引用显示了它是如何被解释的。但是,作为学究,它不需要这样解释--除非在标准引号中有某种形式的优先级。
https://stackoverflow.com/questions/30798661
复制相似问题