声明为consts的函数args在定义时变为非常量

时间:2018-02-01 08:39:55

标签: c++ c++11 c++14 constants

代码

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)和定义(非常量)放在一起,但编译器仍然接受它。如果可以犯错误,最终会犯错误。当存在这种差异时,为什么编译器不能抱怨。

2 个答案:

答案 0 :(得分:5)

来自 11.3.5函数[dcl.fct]

  
      
  1. 单个名称可用于单个中的多个不同功能   范围;这是函数重载(第16条)。所有声明   函数应完全同意返回类型和   参数类型串。使用函数确定函数的类型   遵守规则。每个参数的类型(包括功能   参数包)是由它自己的decl-specifier-seq和   声明符。在确定每个参数的类型后,任何   “T的数组”或函数类型T的参数被调整为   “指向T的指针”。 生成参数类型列表后,任何   修改参数类型时,顶级cv-qualifiers 将被删除   形成功能类型。生成的转换参数列表   类型和省略号或函数的存在或不存在   参数包是函数的参数类型列表。
  2.   

基本上,这意味着,const intint在您的问题中可以互换。

另一方面,如果您添加引用,例如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本身,它只是顶级事情。