代码
class A
{
public:
void f(const int i);
};
void A::f(int i)
{
std::cout<<++i<<std::endl;
}
int main()
{
A a;
a.f(1);
}
为什么编译器在这种情况下不会出错?为什么定义会覆盖常量参数?
此外,当参数类型为reference (&)
时,编译器会抛出错误但在这种情况下为什么不呢?
是否有任何编译器标志可以在上述情况下启用警告?
我对编译器错误POV感兴趣。因为可以很容易地将声明(const)和定义(非常量)放在一起,但编译器仍然接受它。如果可以犯错误,最终会犯错误。当存在这种差异时,为什么编译器不能抱怨。
答案 0 :(得分:5)
来自 11.3.5函数[dcl.fct] :
- 单个名称可用于单个中的多个不同功能 范围;这是函数重载(第16条)。所有声明 函数应完全同意返回类型和 参数类型串。使用函数确定函数的类型 遵守规则。每个参数的类型(包括功能 参数包)是由它自己的decl-specifier-seq和 声明符。在确定每个参数的类型后,任何 “T的数组”或函数类型T的参数被调整为 “指向T的指针”。 生成参数类型列表后,任何 修改参数类型时,顶级cv-qualifiers 将被删除 形成功能类型。生成的转换参数列表 类型和省略号或函数的存在或不存在 参数包是函数的参数类型列表。
醇>
基本上,这意味着,const int
和int
在您的问题中可以互换。
另一方面,如果您添加引用,例如const int&
,const
不再是顶级cv限定符(它将引用值标记为const
),所以编译器抱怨。
通常,const
被添加到定义中,以强调在函数体内不更改参数。
答案 1 :(得分:3)
函数声明
void f(const T arg);
与
相同void f(T arg);
然而,
void f(const T& arg);
与
不同void f(T& arg);
和
void f(const T* arg);
与
不同void f(T* arg);
void f(const T arg);
void f(T arg);
是相同的,因为顶级cv限定符被删除以用于功能解析目的。在那里,const
- ness应用于顶级类型T
。
OTOH,
void f(const T& arg);
void f(T& arg);
不相同,因为const
- ness应用于引用arg
引用的对象,而不是arg
本身,它只是顶级事情。