我写了一篇关于C ++编程的考试。有一个问题我和我的教授不同意。问题是,以下功能是否有效:
#include <iostream>
using namespace std;
void f(int=4, long=10, double=3.14);
int main( int argc , char ** argv )
{
f( , ,8);
return EXIT_SUCCESS;
}
void f(int i, long l, double d) {
cout << i << " " << " " << l << " " << d;
}
我说它不会起作用,但我的教授说它肯定会起作用,因为函数声明中的默认参数。我用MSVC尝试过它并没有用。这是编译器特定的吗?我如何说服我的教授在任何编译器中都不起作用,在考试中提高我的分数?
答案 0 :(得分:6)
首先,你是对的,教授是错的。事实上,他声称这应该有用(当它表明它不重要时)意味着他可能不应该教C ++。但是如何给他看?
尝试使用至少两个不同的编译器进行编译。如果两者都无法编译它,那么它很可能是无效的代码。这是最快的方式。
如果失败,请引用C ++标准。这是调用表达式的语法,如[expr.post] p1和非终端引用之后所述:
postfix-expression:
...
postfix-expression ( expression-list[opt] )
expression-list:
initializer-list
initializer-list: ([dcl.init]p1)
initializer-clause ...[opt]
initializer-list , initializer-clause ...[opt]
initializer-clause:
assignment-expression
braced-init-list
braced-init-list:
{ initializer-list ,[opt] }
{ }
我不打算列出赋值表达式,但请注意表达式永远不会是空的,必须至少有一个令牌。这意味着初始化子句永远不会是空的,因此函数参数中的逗号之间总是存在某种东西。
答案 1 :(得分:4)
从标准(强调我的,特别注意单词尾随):
8.3.6默认参数[dcl.fct.default]
如果在参数声明中指定了initializer子句,则此initializer子句将用作默认参数。 默认参数将用于缺少尾随参数的调用中。
- 醇>
[例如:声明
void point(int = 3, int = 4);
声明一个可以使用类型为int的零个,一个或两个参数调用的函数。它可以通过以下任何方式调用:
point(1,2); point(1); point();
最后两个电话分别相当于
point(1,4)
和point(3,4)
。- 结束示例]
享受积分回报。 ;)
答案 2 :(得分:1)
这甚至不是有效的C ++ 语法。
答案 3 :(得分:1)
这可能是因为它仅适用于省略的尾随参数,如msdn所述。尝试调用这样的函数:
f(); // should use all default values for arguments
f(3); // should use 3 for the first, default for the last two
f(2, 5); // uses 2 for first, 5 for second, default for last
f(5, 6, 3.4); // does not use any default values