为什么没有参数标识符的函数在C++中有效?

pro*_*avi 38 c++ syntax function

给定C++中的函数,其参数只是类型且没有标识符,

 void foo1(int, int, int){cout << "called foo1";}
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它:

int main()
{
    foo1(10, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)

为什么这是C++中的有效构造?这只是C++的特质,还是这种声明实际上有一些目的?我们可以实际访问以某种方式传递的参数吗?(这种方法声明在Java中不起作用.)

use*_*301 40

考虑一种情况,您需要提供满足以下原型的功能

void dostuff(int x, int y, int z);
Run Code Online (Sandbox Code Playgroud)

并且说您在2D空间中操作并且不在z您的实现中使用.您可以

void dostuff(int x, int y, int z)
{
    // use x and y
}
Run Code Online (Sandbox Code Playgroud)

然后忽略z,但编译器可能会发现你已定义但未使用z并警告你可能犯了错误.相反,你可以

void dostuff(int x, int y, int )
{
    // use x and y
}
Run Code Online (Sandbox Code Playgroud)

并忽略了.的定义z.编译器将接受并静默地丢弃第三个参数,因为它知道你不想要它.

你不想因为这样的错误而简单地关闭警告

void dostuff(int x, int y, int z)
{
    for (int z = 0; z < MAX; z++)
    {
        // use x and y and z, the local z. 
    }
}
Run Code Online (Sandbox Code Playgroud)

一个命名不佳的循环索引会影响参数z.调用者的输入现在被忽略,这可能会产生不良后果.标记1眼球通常很难发现这个错误,特别是如果局部z被埋在复杂函数深处的某个地方.

只要编译器可以在代码中发现可能的错误,就可以利用它.这对你来说意味着更少的工作.

  • 我个人喜欢用注释实现未使用的参数:`int/*z*/`.这可以提醒我们论证的内容是什么以及它可以用于什么. (7认同)
  • 对于阴影的例子,我认为编译器应该(也)警告阴影本身; 我想不出有太多情况我们故意用另一个局部变量遮蔽参数或局部变量,即使shadowee仍然在shadower范围之外的某处使用. (2认同)

use*_*447 16

像这样的声明

void foo1(int, int, int){cout << "called foo1";}
Run Code Online (Sandbox Code Playgroud)

在声明中清楚地表明,您希望满足函数的要求 - 例如,覆盖基类或接口中的特定函数,例如可以在那里声明为

virtual void foo1(int something, int another, int andAnother) = 0;
Run Code Online (Sandbox Code Playgroud)

但您不打算使用移交给您的参数.

另一个例子是,如果你想将函数移交给另一个函数,该函数需要一个带有三个int参数的void函数的函数指针.

void giveMeFoo( void (*fn)(int, int, int) ) { ... }
Run Code Online (Sandbox Code Playgroud)

此外,如果声明了参数,则更高的警告级别会发出警告,但不会在函数体中进行评估.您可以通过保留参数名称来避免这种情况.

然后,在函数体中确实无法访问没有名称的参数 - 故意.user4581301很好地描述了,为什么.

由于上面描述的用法,允许声明一个没有参数名称的独立函数,如上例所示,但在大多数情况下显然没有意义.它确实有意义的一个例子是在评论部分.没有参数名称的独立函数的另一个例子可能是,如果您正在编写库并且想要保持向后兼容性(您的库函数不再需要参数,但您不想破坏公共头声明)或者您想保留一个参数以备将来使用.

  • 带有未命名参数的自由函数不是废话,它并不常见.参见[标准示例](http://en.cppreference.com/w/cpp/language/operator_incdec). (4认同)

msc*_*msc 10

是的.它在C++中是合法的.

C++ 11 n3337标准8.4.1(p6)函数定义:

注意:无需命名未使用的参数.例如,

void print(int a, int) {
    std::printf("a = %d\n", a);
}
Run Code Online (Sandbox Code Playgroud)

C++ 14标准:

[8.3.5.11] 可以选择提供标识符作为参数名称; 如果存在于函数定义中,它会命名一个参数(有时称为"形式参数").[注意:特别是,参数名称在函数定义和名称中也是可选的,用于不同声明中的参数,并且函数的定义不必相同.

  • 这不回答这个问题. (8认同)
  • @juanchopanza严格来说,确实如此.为什么有效?因为标准明确地这样说.当然,它没有详细说明. (7认同)
  • 我不认为"它为什么有效?" "因为它是"回答问题.编辑:实际上,我猜它回答"我们可以实际访问以某种方式传递的参数吗?" (2认同)

Car*_*los 7

这是合法的,如果你想知道为什么:

通常,未命名的参数来自代码的简化或提前规划扩展.在这两种情况下,将参数保留在原位(尽管未使用)可确保调用者不受更改的影响.

摘录自:Bjarne Stroustrup."C++编程语言,第四版."