2008-10-14 24 views
6

¿Existe un buen método para escribir encabezados de funciones C/C++ con parámetros predeterminados que son llamadas a funciones?¿Se puede utilizar el resultado de una llamada de función como valor de parámetro predeterminado?

Tengo algunas 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 por defecto. Este valor por defecto ahora tiene que cambiar a algo dinámico y estoy buscando una manera de hacerlo:

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

Dónde bar() es una función que genera el valor por defecto basado en algunos parámetros del sistema. Alternativamente este prototipo de la función se vería así:

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

Cuando Baz es una función que pertenece a un objeto que no se ha creado una instancia en el archivo de cabecera.

+0

AFAIK esto es relevante para C++ no C (C no admite valores predeterminados). – Motti

Respuesta

6

Sí. Lo que has escrito funciona.

+0

¿De verdad? Yo nunca lo hubiera pensado. – Dima

+0

Lol. Rechacé esto como obviamente incorrecto antes de probarlo yo mismo. –

+0

¡He estado programando C++ durante 8 años y no sabía esto! – Justsalt

1

Debería ser perfectamente válido llamar a una función global o hacer referencia a 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.

7

yo utilizo 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 a ser inline, entonces es probable que pequeñas a cero la penalización en el rendimiento. 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.

+0

La sugerencia sobre el uso de funciones sobrecargadas es buena, pero el código en la questoin funciona tal cual. – Charlie

6

¿Qué tiene de malo simplemente eliminar el parámetro opcional en la primera declaración y proporcionar 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.

0

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

clase Foo { pública:

barra static int(); };

allí tendría que declarar:

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

Si necesita objetos diferentes, pase la instancia del objeto.

2

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

4

En la norma, sección 8.3.6 (Argumentos por defecto), 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 firmas usadas como esto:

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

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

Cuestiones relacionadas