tipos salida referencia que por paso parametros parametro funciones entrada ejercicios con c++ pass-by-reference default-value

salida - que es un parametro en c++



Valor predeterminado de un parámetro al pasar por referencia en C++ (15)

const virtual ULONG Write (ULONG & State = 0, bool sequence = true);

La respuesta es bastante simple y no soy tan bueno para explicar, pero si quieres pasar un valor predeterminado a un parámetro no const, que probablemente se modifique en esta función es usarlo así:

virtual const ULONG Write(ULONG &State = *(ULONG*)0, bool sequence = > true);

¿Es posible dar un valor predeterminado a un parámetro de una función mientras pasamos el parámetro por referencia? en C ++

Por ejemplo, cuando trato de declarar una función como:

virtual const ULONG Write(ULONG &State = 0, bool sequence = true);

Cuando hago esto, me da un error:

error C2440: ''argumento predeterminado'': no ​​se puede convertir de ''const int'' a ''unsigned long &'' Una referencia que no es ''const'' no se puede vincular a un valor no-l


Creo que no, y la razón es que los valores predeterminados se evalúan en constantes y los valores pasados ​​por referencia deben poder cambiar, a menos que también declare que es una referencia constante.


En caso de OO ... Decir que una Clase dada tiene y "Predeterminado" significa que este Valor por Defecto (default) debe declararse de forma acondi- cionante y luego puede ser usd como un Parámetro por defecto ex:

class Pagination { public: int currentPage; //... Pagination() { currentPage = 1; //... } // your Default Pagination static Pagination& Default() { static Pagination pag; return pag; } };

En tu Método ...

shared_ptr<vector<Auditoria> > findByFilter(Auditoria& audit, Pagination& pagination = Pagination::Default() ) {

Esta solución es bastante adecuada ya que en este caso, "paginación predeterminada global" es un único valor de "referencia". También tendrá la capacidad de cambiar los valores predeterminados en el tiempo de ejecución, como una configuración de nivel "gobal", por ejemplo: preferencias de navegación de paginación del usuario, etc.


Es posible con const qualifier para State:

virtual const ULONG Write(const ULONG &State = 0, bool sequence = true);


Esta pequeña plantilla te ayudará a:

template<typename T> class ByRef { public: ByRef() { } ByRef(const T value) : mValue(value) { } operator T&() const { return((T&)mValue); } private: T mValue; };

Entonces podrás:

virtual const ULONG Write(ULONG &State = ByRef<ULONG>(0), bool sequence = true);


Hay dos razones para pasar un argumento por referencia: (1) para el rendimiento (en cuyo caso desea pasar por referencia constante) y (2) porque necesita la capacidad de cambiar el valor del argumento dentro de la función.

Dudo mucho que pasar un largo sin firmar en las arquitecturas modernas te ralentice demasiado. Así que supongo que tiene la intención de cambiar el valor de State dentro del método. El compilador se queja porque la constante 0 no se puede cambiar, ya que es un valor r ("non-lvalue" en el mensaje de error) e inmutable ( const en el mensaje de error).

En pocas palabras, quiere un método que puede cambiar el argumento pasado, pero de forma predeterminada desea pasar un argumento que no puede cambiar.

Para decirlo de otra manera, las referencias no const deben referirse a variables reales. El valor predeterminado en la firma de la función ( 0 ) no es una variable real. Te encuentras con el mismo problema que:

struct Foo { virtual ULONG Write(ULONG& State, bool sequence = true); }; Foo f; ULONG s = 5; f.Write(s); // perfectly OK, because s is a real variable f.Write(0); // compiler error, 0 is not a real variable // if the value of 0 were changed in the function, // I would have no way to refer to the new value

Si no tiene la intención de cambiar el State dentro del método, simplemente puede cambiarlo a const ULONG& . Pero no obtendrá un gran beneficio de rendimiento de eso, por lo que le recomendaría cambiarlo a ULONG no de referencia. Noto que ya está devolviendo un ULONG , y tengo una sospecha furtiva de que su valor es el valor del State después de cualquier modificación necesaria. En ese caso, simplemente declararía el método como tal:

// returns value of State virtual ULONG Write(ULONG State = 0, bool sequence = true);

Por supuesto, no estoy muy seguro de lo que estás escribiendo ni de dónde. Pero esa es otra pregunta para otro momento.


No puede usar un literal constante para un parámetro predeterminado por el mismo motivo por el que no puede usar uno como parámetro para la llamada a la función. Los valores de referencia deben tener una dirección, los valores de referencias constantes no necesitan (es decir, pueden ser valores r o literales constantes).

int* foo (int& i ) { return &i; } foo(0); // compiler error. const int* bar ( const int& i ) { return &i; } bar(0); // ok.

Asegúrese de que su valor predeterminado tenga una dirección y que está bien.

int null_object = 0; int Write(int &state = null_object, bool sequence = true) { if( &state == &null_object ) { // called with default paramter return sequence? 1: rand(); } else { // called with user parameter state += sequence? 1: rand(); return state; } }

He usado este patrón varias veces cuando tenía un parámetro que podía ser variable o nulo. El enfoque habitual es hacer que el usuario pase un puntero en este caso. Pasan un puntero NULL si no quieren que ingreses el valor. Me gusta el enfoque de objeto nulo. Hace la vida de los llamantes más fácil sin complicar terriblemente el código de llamada.


No, no es posible.

Pasar por referencia implica que la función puede cambiar el valor del parámetro. Si la persona que llama no proporciona el parámetro y proviene de la constante predeterminada, ¿qué función se supone que cambiará?


Otra forma podría ser la siguiente:

virtual const ULONG Write(ULONG &State, bool sequence = true); // wrapper const ULONG Write(bool sequence = true) { ULONG dummy; return Write(dummy, sequence); }

entonces las siguientes llamadas son posibles:

ULONG State; object->Write(State, false); // sequence is false, "returns" State object->Write(State); // assumes sequence = true, "returns" State object->Write(false); // sequence is false, no "return" object->Write(); // assumes sequence = true, no "return"


Puede hacerlo por una referencia constante, pero no por una constante. Esto se debe a que C ++ no permite que un temporal (el valor predeterminado en este caso) se vincule a la referencia no constante.

Una forma de evitar esto sería usar una instancia real como predeterminada:

static int AVAL = 1; void f( int & x = AVAL ) { // stuff } int main() { f(); // equivalent to f(AVAL); }

pero esto tiene un uso práctico muy limitado.


También hay un truco bastante sucio para esto:

virtual const ULONG Write(ULONG &&State = 0, bool sequence = true);

En este caso, debe llamarlo con std::move :

ULONG val = 0; Write(std::move(val));

Es solo una solución divertida, ¡ no lo recomiendo usar en código real!


Todavía existe la antigua forma C de proporcionar argumentos opcionales: un puntero que puede ser NULL cuando no está presente:

void write( int *optional = 0 ) { if (optional) *optional = 5; }


Ya se dijo en uno de los comentarios directos a su respuesta, pero solo para decirlo oficialmente. Lo que quieres usar es una sobrecarga:

virtual const ULONG Write(ULONG &State, bool sequence); inline const ULONG Write() { ULONG state; bool sequence = true; Write (state, sequence); }

El uso de sobrecargas de funciones también tiene beneficios adicionales. En primer lugar, puede predeterminar cualquier argumento que desee:

class A {}; class B {}; class C {}; void foo (A const &, B const &, C const &); void foo (B const &, C const &); // A defaulted void foo (A const &, C const &); // B defaulted void foo (C const &); // A & B defaulted etc...

También es posible redefinir los argumentos predeterminados a las funciones virtuales en la clase derivada, lo que evita la sobrecarga:

class Base { public: virtual void f1 (int i = 0); // default ''0'' virtual void f2 (int); inline void f2 () { f2(0); // equivalent to default of ''0'' } }; class Derived : public Base{ public: virtual void f1 (int i = 10); // default ''10'' using Base::f2; virtual void f2 (int); }; void bar () { Derived d; Base & b (d); d.f1 (); // ''10'' used b.f1 (); // ''0'' used d.f2 (); // f1(int) called with ''0'' b.f2 (); // f1(int) called with ''0 }

Solo hay una situación en la que realmente se necesita usar un valor predeterminado, y eso es en un constructor. No es posible llamar a un constructor de otro, por lo que esta técnica no funciona en ese caso.


void f(const double& v = *(double*) NULL) { if (&v == NULL) cout << "default" << endl; else cout << "other " << v << endl; }


void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);