函数原型和函数实现签名是否可以使用const不一致?

fut*_*lib 8 c c++ const header function-prototypes

我喜欢const在可能的情况下声明偶数值参数,通过搜索SO,我发现这并不常见.像这样:

int add(const int a, const int b)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

但我想知道:const因为是我的函数的实现细节,而不是它的接口的一部分.因此将它放入原型似乎是不必要的.

这个上述函数的原型似乎工作得很好:

int add(int a, int b);
Run Code Online (Sandbox Code Playgroud)

然而,我听说过一些问题,例如将main函数的argc声明为const会导致问题:

int main(const int argc, const char* const argv[])
Run Code Online (Sandbox Code Playgroud)

这是否意味着,int add(int a, int b)int add(const int a, const int b)终究不是相同?

如果它在技术上还可以,我应该做些什么?我也可以在原型中省略变量名,但我没有,所以也许我也不应该遗漏const

Dan*_*rey 10

函数类型不同是不行的,但是你需要知道函数类型的一部分是什么,什么不是.在您的情况下,constfor参数并不重要,因此函数类型是相同的,尽管声明看起来与定义不同.

在你的情况下它是

8.3.5函数[dcl.fct]

5单个名称可用于单个范围内的多个不同功能; 这是函数重载(第13条).函数的所有声明都应在return类型和parameter-type-list中完全一致.使用以下规则确定函数的类型.每个参数的类型(包括函数参数包)由其自己的decl-specifier-seq和声明符确定.在确定每个参数的类型之后,将"T数组"或"函数返回T"类型的任何参数分别调整为"指向T的指针"或"指向函数返回T的指针".生成参数类型列表后,在形成函数类型时,将删除修改参数类型的任何顶级cv限定符.生成的已转换参数类型列表以及省略号或函数参数包的存在与否是函数的parameter-type-list.[注意:此转换不会影响参数的类型.例如,int(*)(const int p, decltype(p)*)并且int(*)(int, const int*)是相同的类型. - 结束说明]

看起来,它需要一些解释,所以我们在这里:我们的例子中的重要句子是:在生成参数类型列表之后,在形成函数类型时,将删除修改参数类型的任何顶级cv限定符.

这意味着将删除所有顶级 cv-qualifier.为了解释顶级意味着什么,我将以非法方式编写类型以强调const所指的内容:

  • const int= (const (int))- >这是顶级的const
  • const int*= ((const (int))*)- >不是顶级,它在第二级
  • const int* const= (((const (int))*) const)- >第二个const是顶级
  • const int&= ((const (int))&)- >不是顶级

我希望这清除了对函数类型的一些误解.

对于你的其他问题:我建议保持声明和定义相同,因为它可能会使人感到困惑(就像这个问题所证明的那样;).

举个例子main你给了:

int main( const int argc, const char* const argv[] )
Run Code Online (Sandbox Code Playgroud)

根据标准的上述引用,相当于:

int main( int argc, const char* const* argv )
Run Code Online (Sandbox Code Playgroud)

因此添加的constfor argv不会最终const被删除,因此它是一个格式错误的函数类型main,它期望:

int main( int argc, char** argv )
Run Code Online (Sandbox Code Playgroud)

关于省略参数名称的最后一个问题:我不会这样做,因为对我来说,它们是函数文档的一部分.它们传达函数的意图和语义(如果你明智地选择它们).

  • @LuchianGrigore:在某些情况下(如上所述),它不是**签名的一部分.在downvoting之前直接了解事实. (5认同)
  • @TonyTheLion:是的,就是这样.注意,这是*top-level*,意思是`const int`被简化为`int`,但`const int*`保持不变.另外:`const int*const`变成`const int*`. (3认同)
  • 抱歉rash downvote(现在+1),这只是你认为你是对的那种情况之一,然后是bam!,C++说没有:) (3认同)
  • 你在说什么?`const`在签名中非常重要. (2认同)