La respuesta breve es sí.
Si el objeto se recibe por función como parámetro de referencia const - como ha modificado el método bar(const A&)
, entonces es totalmente legal. La función puede operar en el objeto, pero el objeto se destruirá después de la llamada a la función (se puede tomar la dirección temporal, pero no se debe almacenar y usar después de la llamada a la función - ver el motivo a continuación).
El foo(A*)
es legal también porque el objeto temporal se destruye al final de la carga completa. Sin embargo, la mayoría del compilador emitirá una advertencia acerca de tomar la dirección de temporal.
La versión original de bar(A&)
no se compilará, es contrario al estándar inicializar una referencia no constante de una temporal.
C++ capítulo estándar 12,2
3 [...] objetos temporales se destruyen como el último paso en la evaluación de la fullexpression (1.9) que (léxico) contiene el punto en el que fueron creados. [...]
4 Hay dos contextos en los que los temporales se destruyen en un punto diferente al final de la vista completa. El primer contexto es cuando aparece una expresión como un inicializador para un declarador que define un objeto. En ese contexto, el temporal que contiene el resultado de la expresión persistirá hasta que se complete la inicialización del objeto. [...]
5 El segundo contexto es cuando una referencia está vinculada a un temporal. El temporal al que se enlaza la referencia o el temporal que es el objeto completo de un subobjeto del cual el temporal está vinculado persiste durante el tiempo de vida de la referencia, excepto como se especifica a continuación. Un límite temporal a un miembro de referencia en un ctorinitializer (12.6.2) del constructor persiste hasta que el constructor sale. Un límite temporal a un parámetro de referencia en una llamada a función (5.2.2) persiste hasta la finalización de la expresión completa que contiene la llamada. Un límite temporal al valor devuelto en una declaración de devolución de función (6.6.3) persiste hasta que la función finaliza.
A fullexpression es una expresión que no es una subexpresión de otra expresión.
, está prohibido tomar la dirección de un rvalue, no un temporal específicamente. es por eso que esto está prohibido; 'A()' devuelve un valor r. –
@underscore_d Verdadero: utilicé el término informal 'temporal', más específicamente una variable temporal sin nombre, y, como bien dices, un valor r. Si estamos siendo quisquillosos, 'A()' no 'devuelve' un valor r (los constructores no tienen valores devueltos), es una expresión prvalue. –
Buena captura: es demasiado fácil pensar reflexivamente en constructores como llamadas a funciones. –