给定C ++中的函数,其参数只是类型且没有标识符,
void foo1(int, int, int){cout << "called foo1";}
我可以这样称呼它:
int main()
{
foo1(10, 10, 10);
}
为什么这是C ++中的有效构造?这只是C ++的特质,还是这种声明实际上有一些目的?我们可以实际访问以某种方式传递的参数吗? (这种方法声明在Java中不起作用。)
答案 0 :(得分:41)
考虑一种情况,您需要提供符合以下原型的功能
void dostuff(int x, int y, int z);
并说您在2D空间中操作,并且不在您的实现中使用z
。你可以
void dostuff(int x, int y, int z)
{
// use x and y
}
并忽略z
,但编译器可能会发现您已定义但未使用z
,并警告您可能会犯错误。相反,你可以
void dostuff(int x, int y, int )
{
// use x and y
}
并忽略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.
}
}
如果命名不佳的循环索引会影响参数z
。调用者的输入现在被忽略,这可能会产生不良后果。标记1眼球通常很难发现此错误,特别是如果本地z
被埋在复杂函数深处的某个地方。
编译器可以随时挑选代码中的可能错误。这对你来说意味着更少的工作。
答案 1 :(得分:16)
像
这样的宣言void foo1(int, int, int){cout << "called foo1";}
在声明中清楚地表明,您希望满足您的功能要求 - 例如覆盖基类或接口中的特定函数,例如,可以在那里宣布为
virtual void foo1(int something, int another, int andAnother) = 0;
但您不打算使用移交给您的参数。
另一个例子是,如果你想把这个功能移交给,例如一个函数指向一个带有三个int参数的void函数的函数指针。
void giveMeFoo( void (*fn)(int, int, int) ) { ... }
此外,如果声明参数,则更高的警告级别会发出警告,但不会在函数体中进行评估。您可以通过保留参数名称来避免这种情况。
然后,在函数体中确实无法访问没有名称的参数 - 故意。 user4581301很好地描述了,为什么。
由于上述用法,允许声明一个没有参数名称的独立函数,如上例所示,但在大多数情况下显然没有意义。它确实有意义的一个例子是在评论部分。没有参数名称的独立函数的另一个例子可能是,如果您正在编写库并且想要保持向后兼容性(您的库函数不再需要参数,但您不想破坏公共头声明)或者您想保留一个参数以备将来使用。
答案 2 :(得分:11)
是即可。它在C ++中是合法的。
C ++ 11 n3337标准8.4.1(p6)函数定义:
注意:无需命名未使用的参数。例如,
void print(int a, int) { std::printf("a = %d\n", a); }
C ++ 14标准:
[8.3.5.11] 可以选择提供标识符作为参数名称;如果存在于函数定义中,则为参数命名 (有时称为“形式论证”)。 [注:特别是参数 名称在函数定义和名称中也是可选的 不同声明中的参数和函数的定义 不必相同。]
答案 3 :(得分:8)
这是合法的,如果您想知道原因:
通常,未命名的参数来自简化代码或 从提前规划扩展。在这两种情况下,离开 虽然未使用,但适当的参数可确保调用者不会 受到变化的影响。
摘录自:Bjarne Stroustrup。 “C ++编程语言,第四版。”
答案 4 :(得分:1)
这个想法是你可能想要改变这个功能 定义以后使用占位符,而不更改所有 调用函数的代码。
函数声明中的参数可以不用声明 身份标识。当这些与默认参数一起使用时,它可以看起来 有点好笑。你最终可以:
void f(int x, int = 0, float = 1.1);
在C ++中,您不需要在函数定义中使用标识符:
void f(int x, int, float flt) { /* ... */ }
在函数体中,可以引用x
和flt,但不能引用
中间论点,因为它没有名字。函数调用仍然必须
但是,为占位符提供值:f(1)
或f(1,2,3.0)
。这个
语法允许您将参数作为占位符放入
使用它。