使用前面的函数参数声明新函数是否合法?

下面的代码用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) ------------------^ 

因此arg1arg2的声明范围内。 我认为这已经足够了。

禁止违约arg2arg1的规则是分开的 – 对我来说,这表明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。 您不能使用它的值 – 因为值的评估顺序是未指定的 – 但是应该从左到右依次引入名称。