Rus*_*lan 35 c++ gcc function language-lawyer
以下代码与GCC完全编译:
void func(int arg1, decltype(arg1) arg2)
{
(void)arg2;
}
int main(){}
Run Code Online (Sandbox Code Playgroud)
我用这个命令编译:
g++ -std=c++14 test.cpp -o test -pedantic-errors -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)
但是在函数声明中间使用参数似乎很奇怪.它在标准C++中实际有效,还是GCC扩展?
Gal*_*lik 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*)是相同的类型.- 结束说明]
Bar*_*rry 11
是的,这是合法的.这基本上只是一个范围问题.来自[basic.scope.block]:
函数参数名称(包括出现在lambda声明符中的函数)或函数定义中的函数本地预定义变量(8.4)的潜在范围从其声明点开始.
范围arg1从这里开始:
void func(int arg1, decltype(arg1) arg2)
------------------^
Run Code Online (Sandbox Code Playgroud)
因此arg1是在宣布的范围内arg2.我认为这已经足够了.
对于不允许拖欠的规则arg2来arg1为不同的-这对我来说意味着arg1在范围上,不得不被明令禁止的.
如果我们查看N3979 [dcl.fct.default],我们有
每次调用函数时都会计算默认参数.函数参数的评估顺序未指定.因此,函数的参数不应在默认参数中使用,即使它们未被评估.在默认参数之前声明的函数的参数在范围内,并且可以隐藏命名空间和类成员名称.[例如:
Run Code Online (Sandbox Code Playgroud)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了调用范围.这使我相信每个函数参数在每个后续参数之前都是已知的.这意味着您应该能够使用其类型.您不能使用其值 - 因为未指定值的评估顺序 - 但应按从左到右的顺序引入名称.