valor tipos retorno referencia por paso pase parametros funciones formales defecto con argumentos c++ parameters default-value

tipos - paso por referencia en c++



¿Se puede utilizar el resultado de una llamada de función como valor de parámetro predeterminado? (8)

¿Existe un buen método para escribir encabezados de funciones C / C ++ con parámetros predeterminados que son llamadas a funciones?

Tengo un encabezado con la función:

int foo(int x, int y = 0);

Estoy trabajando en una gran base de código donde muchas funciones llaman a esta función y dependen de este valor predeterminado. Este valor predeterminado ahora necesita cambiar a algo dinámico y estoy buscando una manera de hacerlo:

int foo(int x, int y = bar());

Donde bar () es alguna función que genera el valor predeterminado en función de algunos parámetros del sistema. Alternativamente, este prototipo de función se vería así:

int foo(int x, int y = baz.bar());

Donde baz es una función que pertenece a un objeto que no ha sido instanciado dentro del archivo de encabezado.



¿Qué hay de malo simplemente eliminando el parámetro opcional en la primera declaración y proporcionando una sola sobrecarga de parámetros?

int foo(int x) { Bar bar = //whatever initialization return foo(x,bar.baz()); } int foo(int x,int y) { //whatever the implementation is right now }

Creo que esto tiende a ser mucho más limpio y más flexible que tratar de usar algún valor predeterminado dinámico.


Debería ser perfectamente válido llamar a una función global o referenciar un objeto global en este contexto, siempre que la declaración de la función / objeto esté dentro del alcance. Puede o no ser aconsejable (en términos de buen diseño), pero debería funcionar.


En el estándar, sección 8.3.6 (Argumentos predeterminados), párrafo 5, dan un ejemplo usando solo este enfoque. Específicamente, indica que los argumentos predeterminados son expresiones , por lo que se aplica una llamada a función, aunque con restricciones como la búsqueda de nombres y la compatibilidad de tipos.

En mi lugar de trabajo, hemos usado firmas como esta:

void An_object::An_object( const Foo &a, const Bar &b, const Strategem &s = Default_strategem() );

para permitir a los clientes anular un comportamiento en un constructor de clase. Fue útil para el comportamiento condicional que afectó el rendimiento de un traductor ...


Intente hacer que bar () sea una función de miembro estática. Esto permitirá que cualquier parte del programa que tenga una clase estática en alcance pueda acceder a él. Por ejemplo:

clase Foo {público:

static int bar (); };

Entonces declararías:

int foo (int x, int y = Foo :: bar ());

Si necesita objetos diferentes, pase en su lugar la instancia del objeto.


Sí. Lo que has escrito funciona.


Tangencial, pero me parece que eso introduciría problemas de dependencia en el futuro. Me gustaría ir con el enfoque de stbuton.myopenid.com.


Usaría dos funciones sobrecargadas:

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

Si permite que la función de reenvío esté en línea, entonces la penalización de rendimiento probablemente sea pequeña a cero. Si mantiene el cuerpo fuera de línea en un archivo sin encabezado, puede haber un costo de rendimiento (que probablemente sea pequeño), pero mucha más flexibilidad en la implementación y un acoplamiento reducido.