void func(int arg1, decltype(arg1) arg2)
{
(void)arg2;
}
int main(){}
我使用以下命令进行编译:
g++ -std=c++14 test.cpp -o test -pedantic-errors -Wall -Wextra
但是在函数声明中间使用参数似乎很奇怪。这在标准C++中是否有效,还是GCC的扩展功能?
void func(int arg1, decltype(arg1) arg2)
{
(void)arg2;
}
int main(){}
我使用以下命令进行编译:
g++ -std=c++14 test.cpp -o test -pedantic-errors -Wall -Wextra
但是在函数声明中间使用参数似乎很奇怪。这在标准C++中是否有效,还是GCC的扩展功能?
这是正常的。甚至ISO C++11标准
将您的情况作为一个示例。
首先,参数在作用域内:
3.3.3 块作用域 [ basic.scope.local ]
2 函数参数名称(包括出现在lambda-declarator中的名称)或函数定义中的函数本地预定义变量的潜在作用域(8.4)从其声明点开始。
可以在此处找到一个示例:
8.3.5 函数 [ dcl.fct ]
5 [ 注意:这种转换不会影响参数的类型。例如,int(*)(const int p, decltype(p)*) 和 int(*)(int, const int*) 是相同的类型。 — end note ]
C++11
标准在这里出售:http://webstore.ansi.org/RecordDetail.aspx?sku=INCITS%2FISO%2FIEC+14882-2012,但您可以通过搜索“n3290.pdf”获得一个免费的草案(几乎相同?)。 所有的草案直到(但不包括)最终版本都是免费的。 - Galik是的,这是合法的。它基本上只涉及到范围问题。来自 [basic.scope.block]:
函数参数名称(包括出现在lambda-declarator中的参数名称)或函数定义中函数本地预定义变量的潜在作用域(8.4)从其声明点开始。
arg1
的作用域从此处开始:
void func(int arg1, decltype(arg1) arg2)
------------------^
因此,arg1
对于声明 arg2
是在作用域内的。我认为这就足够了。
禁止把 arg2
默认值设为 arg1
的规则是单独的 - 这对我来说意味着 arg1
是在作用域内且必须显式地被禁止。
如果我们查看N3979 [dcl.fct.default],我们会发现:
Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. Parameters of a function declared before a default argument are in scope and can hide namespace and class member names. [ Example:
int a; int f(int a, int b = a); // error: parameter a // used as default argument typedef int I; int g(float I, int b = I(2)); // error: parameter I found int h(int a, int b = sizeof(a)); // error, parameter a used // in default argument
[...]
强调是我的
因此,在示例中,当我们到达b
时,已经知道了a
,并且它从调用范围隐藏了a
。这使我相信在每个后续参数之前都应该知道每个函数参数。这意味着您应该能够使用其类型。您不能使用其值 - 因为值的评估顺序未指定 - 但名称应按从左到右的顺序引入。
decltype
来使用它们。 - NathanOliver
arg1
类型更加复杂,否则我甚至不会考虑尝试使用decltype
。 - Ruslanarg1
,并且对于arg2
也是同样的类型(只是这个类型很难拼写)。 - Barry