visual ver ventana todos subprocesos studio requiere que los locales inspeccion función evaluación ejecuten depuracion autos automatico c++ function gcc language-lawyer

c++ - ver - ¿Es legal usar el parámetro de función anterior para declarar uno nuevo?



view local variables visual studio 2017 (3)

El siguiente código se compila limpiamente con GCC:

void func(int arg1, decltype(arg1) arg2) { (void)arg2; } int main(){}

Usé este comando para compilar:

g++ -std=c++14 test.cpp -o test -pedantic-errors -Wall -Wextra

Pero ese uso de un parámetro en el medio de la declaración de función parece extraño. ¿Es realmente válido en C ++ estándar o es una extensión de GCC?


Esto esta bien. El ISO C++11 Standard incluso da su situación como ejemplo.

Primero, el parámetro está en el alcance:

3.3.3 Alcance del bloque [ basic.scope.local ]

2 El alcance potencial de un nombre de parámetro de función (incluido uno que aparece en un declarador lambda) o de una variable predefinida local de función en una definición de función (8.4) comienza en su punto de declaración.

Un ejemplo puede ser encontrado aquí:

8.3.5 Funciones [ dcl.fct ]

5 [ Nota: esta transformación no afecta los tipos de los parámetros. Por ejemplo, int (*) (const int p, decltype (p) *) e int (*) (int, const int *) son tipos idénticos. - nota final ]


Si miramos en N3979 [dcl.fct.default] tenemos

Los argumentos predeterminados se evalúan cada vez que se llama a la función. El orden de evaluación de los argumentos de la función no está especificado. En consecuencia, los parámetros de una función no se utilizarán en un argumento predeterminado, incluso si no se evalúan. Los parámetros de una función declarada antes de un argumento predeterminado están dentro del alcance y pueden ocultar nombres de espacio de nombres y miembros de clase . [Ejemplo:

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

[...]

Énfasis mío

Entonces en el ejemplo a se sabe cuando llegamos a b y oculta la a del alcance de la llamada. Esto me lleva a creer que cada parámetro de función se conoce antes de cada parámetro posterior. Esto significa que deberías poder usar su tipo. No puede usar su valor, ya que el orden de evaluación de los valores no está especificado, pero los nombres deben introducirse en orden de izquierda a derecha.


Si, es legal Básicamente es solo una cuestión de alcance. Desde [basic.scope.block]:

El alcance potencial de un nombre de parámetro de función (incluido uno que aparece en un declarador lambda ) o de una variable predefinida local de función en una definición de función (8.4) comienza en su punto de declaración.

El alcance de arg1 comienza aquí:

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

Por lo tanto, arg1 está en el alcance de la declaración de arg2 . Creo que es suficiente.

La regla para no admitir arg2 por defecto a arg1 es separada, lo que a mí me sugiere que arg1 estaba dentro del alcance y tuvo que ser explícitamente desautorizada.