代码之家  ›  专栏  ›  技术社区  ›  Ruslan PiotrNycz

使用前一个函数参数声明新参数合法吗?

  •  35
  • Ruslan PiotrNycz  · 技术社区  · 9 年前

    以下代码可以用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扩展?

    3 回复  |  直到 9 年前
        1
  •  22
  •   Galik    9 年前

    这很好。这个 ISO C++11 Standard 甚至以你的情况为例。

    首先,参数在范围内:

    3.3.3 阻止范围 [ 基本范围局部 ]

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

    示例如下:

    8.3.5 功能 [ 数据中心功能 ]

    5. [ 注意:此转换不影响参数的类型。例如,int(*)(const int p,decltype(p)*)和int(*,int,const int*)是相同的类型。尾注 ]

        2
  •  11
  •   Barry    9 年前

    是的,这是合法的。这基本上只是一个范围问题。来自[basic.scope.block]:

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

    范围 arg1 从这里开始:

    void func(int arg1, decltype(arg1) arg2)
    ------------------^
    

    因此 参数1 在声明范围内 arg2 。我认为这已经足够了。

    不允许违约的规则 参数2 参数1 是分开的,这对我来说意味着 参数1 在范围内,必须明确禁止。

        3
  •  6
  •   Community CDub    4 年前

    如果我们查看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 它隐藏了 从调用范围。这使我相信每个函数参数在每个后续参数之前都是已知的。这意味着您应该能够使用它的类型。您不能使用其值,因为值的求值顺序未指定,但名称应按从左到右的顺序引入。