考虑以下函数声明:
void foo(const int);
此函数具有签名void(int)
。它可以定义如下:
void foo(int) {}
这是有道理的,因为参数在函数体内是否为const对调用者无关紧要。 但是,为什么我们甚至允许在函数声明中编写const参数?
编辑:这不是this question的重复。在该问题中,const
被添加到函数定义中的参数中。他们没有在函数声明中讨论const
参数。
答案 0 :(得分:7)
就C ++语言而言,这两个声明完全等效:
void foo(const int);
void foo(int);
C ++ 11(latest public draft)标准,第13.1节“可重载声明”:
仅在
const
和/或volatile
存在或不存在时不同的参数声明是等效的。也就是说,在确定声明,定义或调用哪个函数时,将忽略每个参数类型的const
和volatile
类型说明符。例如:typedef const int cInt; int f (int); int f (const int); // redeclaration of f(int) int f (int) { /* ... */ } // definition of f(int) int f (cInt) { /* ... */ } // error: redefinition of f(int)
以这种方式只忽略参数类型规范最外层的
const
和volatile
类型说明符;埋在参数类型规范中的const
和volatile
类型说明符很重要,可用于区分重载的函数声明。 124 特别是对于任何类型{{1} },“指向T
的指针”,“指向constT
的指针”和“指向易变T
的指针”被视为不同的参数类型,“T
的引用也是如此,“”引用constT
,“和”引用volatileT
。“124 当参数类型包含函数类型时,例如在参数类型是指向函数的指针的情况下,
T
和{{1}内部函数类型的参数类型规范最外层的type-specifiers也被忽略。
因此,允许函数声明具有const
参数的原因是因为标准说它们等同于具有非volatile
参数的函数声明。
不言而喻,这意味着你不能基于其参数的cv限定来重载函数。
const
类型说明符仅在函数的定义中起作用,它会阻止对该参数的本地修改。
我想没有人能想出一个很好的理由来介绍禁止 const
(和const
)在声明中所需的额外复杂性,当它们是允许且定义重要。
答案 1 :(得分:1)
这是有道理的,因为参数在函数体内是否为const对调用者无关紧要。但是,为什么我们甚至允许在函数声明中编写const参数?
因为声明还引入了定义,const
在定义中很有用。它可以防止意外修改对象。 (默认情况下你应该使用const
“,即你必须使用它。”声明的规则,无论是否引入定义,都是相当广泛的陈述,以保持语言简单。
标准是否会使const
在非定义声明中的by-value参数上写错了?嗯,当然。但它会非常令人困惑,需要更多的标准,而且(正如你所指出的那样)对于任何重要的东西都不会有丝毫的差别。
简而言之,为什么要不遗余力地禁止某些事情?