c++ - 函数原型(prototype)和函数实现签名不一致地使用 const 可以吗?

标签 c++ c header constants function-prototypes

我喜欢在可能的情况下将偶数参数声明为 const,通过搜索 SO,我发现 that's not too uncommon .像这样:

int add(const int a, const int b)
{
    ...
}

但我想知道:valuesconst 是我函数的实现细节,而不是它的接口(interface)的一部分。因此将其放入原型(prototype)中似乎是不必要的。

上述函数的原型(prototype)似乎工作得很好:

int add(int a, int b);

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

int main(const int argc, const char* const argv[])

那么这是否意味着 int add(int a, int b)int add(const int a, const int b) 根本不相同?

如果技术上没问题,那是我应该做的事吗?我也可以在原型(prototype)中省略变量名,但我没有,所以也许我也不应该省略 const

最佳答案

函数类型 不同是不行的,但是您需要知道什么是函数类型的一部分,什么不是。在你的例子中,参数的 const 并不重要,所以函数类型是相同的,尽管 declaration 看起来与 definition.

你的情况是

8.3.5 Functions [dcl.fct]

5 A single name can be used for several different functions in a single scope; this is function overloading (Clause 13). All declarations for a function shall agree exactly in both the return type and the parameter-type-list. The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type. The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function’s parameter-type-list. [ Note: This transformation does not affect the types of the parameters. For example, int(*)(const int p, decltype(p)*) and int(*)(int, const int*) are identical types. — end note ]

看起来,它需要一些解释,所以我们开始:在我们的案例中重要的句子是:在生成参数类型列表之后,任何修改参数类型的顶级 cv-qualifiers 都被删除形成函数类型。

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

  • const int = (const (int)) -> 这是顶级 const
  • const int* = ((const (int))*) -> 不是顶层,是二级
  • const int* const = (((const (int))*) const) -> 第二个 const 在顶部-水平
  • const int& = ((const (int))&) -> 非顶级

我希望这能消除一些关于函数类型的误解。

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

对于您提供的 main 示例:

int main( const int argc, const char* const argv[] )

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

int main( int argc, const char* const* argv )

所以为 argv 添加的 const 最终不会作为顶级 const 被删除,因此它是一个错误的格式main 的函数类型,需要:

int main( int argc, char** argv )

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

关于c++ - 函数原型(prototype)和函数实现签名不一致地使用 const 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15297644/

相关文章:

c++ - Const 正确性 : const char const * const GetName const (//stuff);

c++ - 显示文件中的西里尔文本

c - 为什么具有以下代码的程序会崩溃?如何解决这个问题?

c - 如何打印二维字符数组的内容?

c++ - '{' token 错误之前的预期类名

image - 带有整页背景图片的 wkhtmltopdf

header - 如何添加 Access-Control-Allow-Origin header

c++ - 未使用默认参数

c++ - 将文本文件读入结构并显示数组

c - 简单的 minishell,由于 fgets 的工作方式,无法识别 "quit"以结束程序