以下代码与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扩展?
答案 0 :(得分:22)
这很好。 ISO C++11 Standard
甚至以您的情况为例。
首先参数在范围内:
3.3.3 阻止范围 [ basic.scope.local ]
2 函数参数名称的潜在范围(包括一个出现在lambda声明符中)或者 函数定义(8.4)中的函数本地预定义变量从其声明点开始。
可以在这里找到一个例子:
8.3.5 功能 [ dcl.fct ]
5 [ 注意:此转换不会影响参数的类型。例如,int(*)(const int p,decltype(p)*)和int(*)(int,const int *)是相同的类型。 - 结束说明]
答案 1 :(得分:11)
是的,这是合法的。这基本上只是一个范围问题。来自[basic.scope.block]:
函数参数名称(包括出现在 lambda-declarator 中的名称)或函数定义中的函数本地预定义变量(8.4)的潜在范围从其声明点开始。
arg1
的范围从这里开始:
void func(int arg1, decltype(arg1) arg2)
------------------^
因此,arg1
是arg2
声明的范围。我认为这已经足够了。
禁止违约arg2
到arg1
的规则是分开的 - 对我来说这表明arg1
在范围内并且必须明确禁止。
答案 2 :(得分:6)
如果我们查看N3979 [dcl.fct.default],我们有
每次调用函数时都会计算默认参数。函数参数的评估顺序未指定。因此,函数的参数不应在默认参数中使用,即使它们未被评估。 在默认参数之前声明的函数的参数在范围内,可以隐藏命名空间和类成员名称。 [例如:
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
[...]
强调我的
因此,示例a
在我们到达b
时就已知,并且它会从调用范围隐藏a
。这使我相信每个函数参数在每个后续参数之前都是已知的。这意味着您应该能够使用其类型。您无法使用其值 - 因为未指定值的评估顺序 - 但应按从左到右的顺序引入名称。