¿Puedo establecer un argumento predeterminado de un argumento anterior?

¿Es posible usar argumentos previos en una lista de parámetros de funciones como el valor predeterminado para argumentos posteriores en la lista de parámetros? Por ejemplo,

void f( int a, int b = a, int c = b ); 

Si esto es posible, ¿hay alguna regla de uso?

La respuesta es no, no puedes. Puede obtener el comportamiento que desea utilizando sobrecargas:

 void f(int a, int b, int c); inline void f(int a, int b) { f(a,b,b); } inline void f(int a) { f(a,a,a); } 

En cuanto a la última pregunta, C no permite los parámetros predeterminados en absoluto.

No, eso no es legal C ++. Esto se especifica en la sección 8.3.6 / 9 del Estándar C ++:

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 expresiones de argumento predeterminadas, incluso si no se evalúan.

y:

int f (int a, int b = a); // error: parámetro a utilizado como argumento predeterminado

Y C89 al menos no admite valores de parámetros predeterminados.

Como una solución posible, podrías hacer:

 const int defaultValue = -999; // or something similar void f( int a, int b = defaultValue, int c = defaultValue ) { if (b == defaultValue) { b = a; } if (c == defaultValue) { c = b; } //... } 

Esto no es posible

No, no puedes hacer eso.
Seguramente obtendrá un error “La variable local puede no aparecer en este contexto”.

Tu primera idea podría ser hacer algo como esto:

 void something(int a, int b=-1, int c=-1){ if(b == -1) b = a; if(c == -1) c = b; } 

Usé -1 porque esta función solo funciona con valores positivos. Pero, ¿y si alguien usa mi clase y comete un error que termina enviando -1 al método? Todavía se comstackría y ejecutaría, pero el resultado sería impredecible para el usuario. Entonces, lo más inteligente sería eliminar cualquier argumento predeterminado y en su lugar crear varios métodos con el mismo nombre como este:

 void something(int a, int b, int c){ /* Do something with a, b and c */ } void something(int a){ something(a, a, a); } void something(int a, int b){ something(a, b, b); } 

En realidad, no lleva mucho tiempo codificar, y si alguien lo usa en una interfaz de progtwigción con características de autocompletar, mostrará los 3 prototipos posibles.

No creo que puedas hacer eso, ya que es una syntax ilegal. Sin embargo, consulte el estándar C99 en formato pdf ( n1136.pdf ).

Sin embargo, puede evitar esto usando static como en declarar las variables estáticas y usarlas dentro de la función f

 static int global_a;

 / * En algún otro lugar donde llame f (), haga esto de antemano * /
 / * global_a = 4;  F();  * /

 void f (void) {
    int a = global_a;
    b = c = a;
    / * ..... * /
 }

¡Felicitaciones a Michael Burr por señalar mi error! 🙂

Parece que necesitas replantear tu código y cambiarlo para algo así.