¿Es posible dar un valor predeterminado a un parámetro de una función mientras estamos pasando el parámetro por referencia? en C ++
Por ejemplo, cuando intento declarar una función como:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Cuando hago esto, da un error:
error C2440: 'argumento predeterminado': no se puede convertir de 'const int' a 'unsigned long &' Una referencia que no sea 'const' no se puede vincular a un valor que no sea l
c++
pass-by-reference
default-value
Dibujó Noakes
fuente
fuente
WxWidgets style guide says "don't use templates" and they have good reasons
<- tornillo std :: vector, digoRespuestas:
Puede hacerlo para una referencia constante, pero no para una no constante. Esto se debe a que C ++ no permite que un temporal (el valor predeterminado en este caso) se vincule a una referencia no constante.
Una forma de evitar esto sería usar una instancia real como predeterminada:
pero esto tiene un uso práctico muy limitado.
fuente
Ya se ha dicho en uno de los comentarios directos a su respuesta, pero solo para expresarlo oficialmente. Lo que quieres usar es una sobrecarga:
El uso de sobrecargas de funciones también tiene beneficios adicionales. En primer lugar, puede predeterminar cualquier argumento que desee:
También es posible redefinir argumentos predeterminados para funciones virtuales en la clase derivada, lo que evita la sobrecarga:
Solo hay una situación en la que realmente se necesita usar un valor predeterminado, y es en un constructor. No es posible llamar a un constructor desde otro, por lo que esta técnica no funciona en ese caso.
fuente
d.f2(); // f2(int) called with '0' b.f2(); // f2(int) called with '0'
Todavía existe la antigua forma de C de proporcionar argumentos opcionales: un puntero que puede ser NULL cuando no está presente:
fuente
Esta pequeña plantilla te ayudará a:
Entonces podrás:
fuente
ByRef
vivir, en cuanto a memoria? ¿No es un objeto temporal que se destruiría al dejar algún alcance (como el constructor)?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é se supone que debe cambiar la función?
fuente
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 tiempo sin firmar en arquitecturas modernas te esté frenando 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 constante0
no se puede cambiar, ya que es un rvalue ("non-lvalue" en el mensaje de error) e inmutable (const
en el mensaje de error).En pocas palabras, desea un método que pueda cambiar el argumento pasado, pero de forma predeterminada desea pasar un argumento que no puede cambiar.
Dicho de otra manera, las no
const
referencias deben referirse a variables reales. El valor predeterminado en la función signatura (0
) no es una variable real. Te encuentras con el mismo problema que:Si realmente no tiene la intención de cambiar
State
dentro del método, simplemente puede cambiarlo a unconst ULONG&
. Pero no obtendrá un gran beneficio de rendimiento de eso, por lo que recomendaría cambiarlo a uno que no sea de referenciaULONG
. Me doy cuenta de que ya está devolviendo aULONG
, y tengo la astuta sospecha de que su valor es el valor deState
después de las modificaciones necesarias. En cuyo caso simplemente declararía el método así:Por supuesto, no estoy muy seguro de qué estás escribiendo ni hacia dónde. Pero esa es otra pregunta para otro momento.
fuente
No puede usar un literal constante para un parámetro predeterminado por la misma razón que no puede usar uno como parámetro para la llamada de 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).
Asegúrese de que su valor predeterminado tenga una dirección y esté bien.
He usado este patrón varias veces donde tenía un parámetro que podría ser una variable o nulo. El enfoque habitual es que el usuario pase un puntero, en este caso. Pasan un puntero NULL si no quieren que usted complete el valor. Me gusta el enfoque de objeto nulo. Facilita la vida de las personas que llaman sin complicar terriblemente el código de la persona que llama.
fuente
Creo que no, y la razón es que los valores predeterminados se evalúan como constantes y los valores pasados por referencia deben poder cambiar, a menos que también lo declare como referencia constante.
fuente
Otra forma podría ser la siguiente:
entonces son posibles las siguientes llamadas:
fuente
fuente
En el caso de OO ... Decir que una Clase dada tiene y "Predeterminado" significa que este (valor) Predeterminado debe declararse de forma adicional y luego puede usarse como Parámetro predeterminado, por ejemplo:
En tu método ...
Esta solución es bastante adecuada ya que en este caso, la "Paginación global predeterminada" es un único valor de "referencia". También tendrá el poder de cambiar los valores predeterminados en tiempo de ejecución, como una configuración de "nivel global", por ejemplo: preferencias de navegación de paginación del usuario, etc.
fuente
Es posible con el calificador const para el estado:
fuente
fuente
También hay un truco bastante sucio para esto:
En este caso tienes que llamarlo con
std::move
:Es solo una solución divertida, ¡ no recomiendo totalmente su uso en código real!
fuente
Tengo una solución para esto, vea el siguiente ejemplo sobre el valor predeterminado para
int&
:Puede hacerlo para cualquier tipo de datos trivial que desee, como
bool
,double
...fuente
Defina 2 funciones de sobrecarga.
fuente
La respuesta es bastante simple y no soy tan bueno para explicar, pero si desea pasar un valor predeterminado a un parámetro no constante que probablemente se modificará en esta función, debe usarlo así:
fuente