C++ 使用以前的函数参数声明新的函数参数合法吗?

C++ 使用以前的函数参数声明新的函数参数合法吗?,c++,function,gcc,language-lawyer,C++,Function,Gcc,Language Lawyer,以下代码使用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扩展?< /P> < P>如果我们查看N39 79 [DCL,FCT.DELAT

以下代码使用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扩展?< /P> < P>如果我们查看N39 79 [DCL,FCT.DELATION],我们有< /P> 每次调用函数时都会计算默认参数。未指定函数参数的求值顺序。因此,在默认参数中不应使用函数的参数,即使未对其进行求值在默认参数之前声明的函数的参数在作用域中,可以隐藏命名空间和类成员名称。[示例:

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
。这使我相信每个函数参数在每个后续参数之前都是已知的。这意味着您应该能够使用它的类型。您不能使用它的值-因为值的求值顺序是未使用的cified-但是名称应该按从左到右的顺序介绍。

是的,这是合法的。基本上只是范围问题。从[basic.scope.block]开始:

函数参数名(包括lambda声明符中出现的参数名)或函数定义(8.4)中函数局部预定义变量的潜在范围从其声明点开始

arg1
的范围从这里开始:

void func(int arg1, decltype(arg1) arg2)
------------------^
因此,
arg1
arg2
声明的范围内。我认为这就足够了


禁止将
arg2
默认设置为
arg1
的规则是独立的——我认为
arg1
在范围内,必须明确禁止。

这很好。
ISO C++11标准
甚至给出了您的情况作为示例

首先,参数在范围内:

3.3.3块范围[basic.scope.local]

2函数参数名称(包括lambda声明符中出现的名称)或 函数定义(8.4)中的函数局部预定义变量从其声明点开始

可以在此处找到一个示例:

8.3.5功能[dcl.fct]

5[注意:此转换不影响参数的类型。例如,int(*)(常量int p,decltype(p)*)和int(*)(int,常量int*)是相同的类型。-结束说明]


我认为,在C++中,代码类型> ARG1在实际代码中要复杂得多,而且不需要看规范或任何引用,但是知道一些解析,我想它没问题,因为解析像C++这样的语言是一个自上而下的左到右事件。e> 它必须已经解析了
arg1
的声明,因此它肯定知道
arg1
的类型。如果它真的“允许”,我不知道它是否会朝相反的方向工作(对于
arg1
,使用
decltype(arg2)
)@JoachimPileborg当然,实际代码对于
arg1
的类型要复杂得多,否则我甚至会考虑尝试在其上使用
decltype
。FWIW、MSVC++2013及其Intellisense(EDG)都接受它。匹配参数参数的首选方法是通过模板参数(虽然这不是问题所要问的),但我认为你的建议是有效的。@callyalater,但它不是函数模板。OP希望为
arg1
指定一个特定类型,为
arg2
指定同一类型(只是该类型显然是一个拼音符号)它们确实在范围内,但这足够吗?@MSalters可以将它们与
decltype
一起使用,我想是这样。@AaronHall
C++11
standard在这里出售:但是你可以通过谷歌搜索“n3290.pdf”获得一份免费草稿(几乎完全相同)。所有草稿到(但不包括)最终稿都是免费的。