使用前面的函数参数声明新函数是否合法?
下面的代码用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 Standard
甚至以您的情况为例。
首先参数在范围内:
3.3.3块范围[ basic.scope.local ]
2函数定义(8.4)中函数参数名称的潜在范围(包括出现在lambda声明符中的函数参数名称)或函数本地预定义variables的潜在范围从声明点开始。
一个例子可以在这里find:
8.3.5函数[ dcl.fct ]
5 [注意:此转换不会影响参数的types。 例如,int(*)(const int p,decltype(p)*)和int(*)(int,const int *)是相同的types。 – 结束注意]
是的,这是合法的。 这基本上只是一个范围问题。 来自[basic.scope.block]:
函数定义(8.4)中的函数参数名称(包括出现在lambda声明符中的函数参数名称)或函数本地预定义variables的潜在作用域从声明点开始。
arg1
的范围从这里开始:
void func(int arg1, decltype(arg1) arg2) ------------------^
因此arg1
在arg2
的声明范围内。 我认为这已经足够了。
禁止违约arg2
到arg1
的规则是分开的 – 对我来说,这表明arg1
在范围之内,必须被明确禁止。
如果我们查看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
[…]
强调我的
所以在这个例子中,我们知道当我们到达b
,它隐藏了调用范围中的a。 这使我相信每个函数参数在每个后续参数之前是已知的。 这意味着你应该能够使用它的types。 您不能使用它的值 – 因为值的评估顺序是未指定的 – 但是应该从左到右依次引入名称。