2010-08-17 13 views

Respuesta

14

si tuviera void func(int a = 0, int b);, ¿cómo especificaría utilizar el parámetro predeterminado para llamar a esta función?

+6

Sé que no se puede en C++, pero otros lenguajes lo manejan con 'func (, some_val_for_b)', o parámetros nombrados. –

+1

@Dominic Rodger: para mí eso se ve realmente feo. – dierre

+2

@Dominic Rodger, bueno, C++ no. Si lo desea, puede demandar a Stroupstroup: P –

-1

Porque en una llamada de función tiene que llamar a los argumentos no predeterminados en cualquier caso. Si coloca su argumento predeterminado al principio de la lista de argumentos, ¿cómo se supone que debe decir que está configurando el argumento predeterminado o los otros?

+1

¿Qué es lo que hace que el comienzo de una lista sea tan diferente desde el final de la lista? ¡Las listas son simétricas! –

+2

Sí, pero imagine esto: void func (int a, int b = 0, int c, int d = 0); ¿Qué estás haciendo cuando llamas a func (1, 2, 3); –

+0

¿Y qué extremo de la lista, exactamente, está 'b' en? –

1

Solo para complementar la respuesta de @ tenfour. Preguntas frecuentes sobre C++ Lite tiene un tema que describe named parameters y creo que el tema aborda su problema hasta cierto punto.

5

Porque así es como se ha diseñado el lenguaje.

Una pregunta más interesante sería: ¿cuáles son las alternativas?

Suponga que tiene void f(A a = MyA, B b);

  • marcador de posición/argumento en blanco: f(_, abee) o f(, abee)
  • argumentos con nombre (como en Python): f(b = abee)

pero esas son sutilezas y ciertamente no es necesario, porque a diferencia de Python, C++ admite la sobrecarga de funciones:

  • void f(A a, B b);
  • void f(B b) { f(MyA, b); }

y por lo tanto los argumentos por defecto son innecesarias ... sobre todo teniendo en cuenta que hay problemas cuando se utiliza con OO-código, porque los argumentos por defecto se resuelven de forma estática (en tiempo de compilación)

struct Base 
{ 
    virtual void func(int g = 3); 
}; 

struct Derived 
{ 
    virtual void func(int g = 4); 
}; 

int main(int argc, char* argv[]) 
{ 
    Derived d; 
    d.func(); // Derived::func invoked with g == 4 

    Base& b = d; 
    b.func(); // Derived::func invoked with g == 3 (AH !!) 
} 

EDIT: de parámetros con nombre ->

El la característica se puede emular usando objetos de función.

class Func 
{ 
public: 
    Func(B b): mA(MyA), mB(b) {} 

    A& a(A a) { mA = a; } 
    B& b(B b) { mB = b; } 

    void operator()() { func(mA, mB); } 
private: 
    A mA; 
    B mB; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a; B b; 
    Func(b)(); 
    Func(b).a(a)(); 
} 

En caso de que no desea copiar los argumentos, usted tiene la posibilidad de utilizar referencias/punteros aunque puede complicarse.

Es un modismo práctico cuando tiene un montón de valores predeterminados sin un orden de prioridad real.

+0

La sobrecarga de funciones no ayuda si 'A' y' B' son del mismo tipo ... –

+0

@Oli: ¿por qué? dado el primer prototipo de 'func', está claro que si hay un solo parámetro, entonces el valor predeterminado debe usarse para el primer parámetro, cualquiera que sea su tipo. Sin embargo, las cosas se ponen feas cuando tienes dos valores predeterminados;) En general, los parámetros nombrados son lo único que puede resolver el problema, y ​​lo mejor es que son una solución en tiempo de compilación. –

+0

Sí, tienes razón. Pensé que estabas usando sobrecarga para eliminar la ambigüedad de 'func (A a, B b)', 'func (B b)' * y * 'func (A a)'. –

Cuestiones relacionadas