functional classes array c++ function syntax

classes - string c++



¿Por qué una función sin identificadores de argumento es válida en C++? (5)

Considere un caso en el que debe proporcionar una función que cumpla con el siguiente prototipo

void dostuff(int x, int y, int z);

Y digamos que está operando en un espacio 2D y no usa z dentro de su implementación. Usted puede

void dostuff(int x, int y, int z) { // use x and y }

y simplemente ignore z , pero es probable que el compilador detecte que ha definido pero no usado z y le advierte que podría estar cometiendo un error. En cambio, puedes

void dostuff(int x, int y, int ) { // use x and y }

y omite la definición de z . El compilador aceptará y descartará silenciosamente el tercer parámetro porque sabe que no lo quiere.

No desea simplemente desactivar la advertencia debido a errores como este

void dostuff(int x, int y, int z) { for (int z = 0; z < MAX; z++) { // use x and y and z, the local z. } }

Donde un índice de bucle mal llamado sombrea el parámetro z . La entrada de la persona que llama ahora se ignora y esto podría tener malas consecuencias. Este error a menudo es difícil de detectar con el ojo de la marca 1, especialmente si la z local está enterrada en alguna parte profunda de una función compleja.

Cada vez que el compilador puede eliminar un posible error en su código, aproveche. Significa menos trabajo para ti.

Dada una función en C ++ con argumentos que son solo tipos y no tienen identificadores,

void foo1(int, int, int){cout << "called foo1";}

Puedo llamarlo así:

int main() { foo1(10, 10, 10); }

¿Por qué es esto una construcción válida en C ++? ¿Es solo una idiosincrasia de C ++, o este tipo de declaración en realidad tiene algún propósito? ¿Podemos acceder a los argumentos que se han pasado de alguna manera? (Este tipo de declaración de método no funcionará en Java).


Es legal, y si se pregunta por qué:

Normalmente, los argumentos sin nombre surgen de la simplificación del código o de la planificación anticipada de las extensiones. En ambos casos, dejar el argumento en su lugar, aunque no se use, asegura que las personas que llaman no se vean afectadas por el cambio.

Extracto De: Bjarne Stroustrup. "El lenguaje de programación C ++, cuarta edición".


Una declaración como

void foo1(int, int, int){cout << "called foo1";}

muestra claramente en la declaración que desea cumplir un requisito con su función, por ejemplo, anular una función específica en la clase base o interfaz, que podría declararse allí como

virtual void foo1(int something, int another, int andAnother) = 0;

PERO no tiene la intención de utilizar los parámetros que le son entregados.

Otro ejemplo sería si desea transferir la función a, por ejemplo, otra función que espera un puntero de función a una función vacía con tres parámetros int.

void giveMeFoo( void (*fn)(int, int, int) ) { ... }

Además, los niveles de advertencia más altos emiten una advertencia, si se declaran los parámetros, que no se evalúan en el cuerpo de la función. Puede evitar eso dejando los nombres de los parámetros alejados.

Los parámetros sin nombres ya no son accesibles en el cuerpo de la función, a propósito. user4581301 ha descrito muy bien, por qué.

La declaración de una función independiente sin nombres de parámetros como en su ejemplo se permite debido a los usos descritos anteriormente, pero obviamente no tiene sentido en la mayoría de los casos. Un ejemplo donde tiene sentido es en la sección de comentarios. Otro ejemplo de una función independiente sin nombres de parámetros podría ser, si está escribiendo una biblioteca y desea mantener la compatibilidad con versiones anteriores (su función de biblioteca ya no necesita el parámetro, pero no desea romper la declaración del encabezado público) o desea reservar un parámetro para uso futuro.


La idea es que desee cambiar la definición de la función para usar el marcador de posición más adelante, sin cambiar todo el código donde se llama a la función.

Los argumentos en una declaración de función se pueden declarar sin identificadores. Cuando se usan con argumentos predeterminados, puede parecer un poco gracioso. Puedes terminar con:

void f(int x, int = 0, float = 1.1);

En C ++ no necesita identificadores en la definición de la función, ya sea:

void f(int x, int, float flt) { /* ... */ }

En el cuerpo de la función, se puede hacer referencia a x y flt, pero no al argumento del medio, porque no tiene nombre. Las llamadas a funciones aún deben proporcionar un valor para el marcador de posición, sin embargo: f(1) o f(1,2,3.0) . Esta sintaxis le permite poner el argumento como un marcador de posición sin usarlo.


. Es legal en C ++.

C ++ 11 n3337 estándar 8.4.1 (p6) Definiciones de funciones:

Nota: los parámetros no utilizados no necesitan ser nombrados. Por ejemplo,

void print(int a, int) { std::printf("a = %d/n", a); }

Estándar C ++ 14:

[8.3.5.11] Opcionalmente, se puede proporcionar un identificador como nombre de parámetro; si está presente en una definición de función, nombra un parámetro (a veces llamado "argumento formal"). [Nota: en particular, los nombres de los parámetros también son opcionales en las definiciones de función y los nombres utilizados para un parámetro en diferentes declaraciones, y la definición de una función no tiene que ser la misma.]