tutorial smart remix programador online español curso c++ reference const object-lifetime temporary-objects

c++ - remix - smart contracts ethereum



¿Por qué un parámetro de referencia no const se puede vincular a un objeto temporal? (2)

char f1(); void f2(char&); struct A {}; A f3(); void f4(A&); int main() { f2(f1()); // error C2664. This is as expected. f4(f3()); // OK! Why??? }

error C2664: ''void f4 (char &)'': no ​​se puede convertir el argumento 1 de ''char'' a ''char &''

Me han enseñado que en C ++ un parámetro de referencia no constante no puede vincularse a un objeto temporal; y en el código anterior, f2(f1()); desencadena un error como se esperaba.

Sin embargo, ¿por qué la misma regla no se aplica a la línea de código f4(f3()); ?

PD: mi compilador es VC ++ 2013. Incluso si comento la línea f2(f1()); , luego el código que contiene f4(f3()); se compilará sin errores ni advertencias.

Actualizar:

MSDN dice:

En versiones anteriores de Visual C ++, las referencias no const podían vincularse a objetos temporales. Ahora, los objetos temporales solo pueden vincularse a referencias const.

Entonces creo que es un error de VC ++. He enviado un informe de error al equipo de VC ++


Si compila con la opción / Za para deshabilitar las extensiones de idioma, el compilador rechaza ambas llamadas:

> cl /Za test.cpp Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86 Copyright (C) Microsoft Corporation. All rights reserved. test.cpp test.cpp(11): error C2664: ''void f2(char &)'' : cannot convert argument 1 from ''char'' to ''char &'' test.cpp(12): error C2664: ''void f4(A &)'' : cannot convert argument 1 from ''A'' to ''A &'' A non-const reference may only be bound to an lvalue

Hay varias circunstancias (muy limitadas) en las que el compilador, con las extensiones de idioma habilitadas, aún permitirá una referencia de valor l no const para vincularse a una expresión rvalue. Según tengo entendido, esto se debe principalmente a evitar romper varias bases de código heredadas que dependen de esta "extensión".

(En general, el uso de / Za no se recomienda por muchas razones, sino principalmente porque los encabezados del SDK de Windows no pueden #incluirse con la opción / Za).


Su compilador no es compatible con el estándar (tal vez esto es una extensión del compilador documentada?). GCC da los siguientes errores:

main.cpp: In function ''int main()'': main.cpp:11:11: error: invalid initialization of non-const reference of type ''char&'' from an rvalue of type ''char'' f2(f1()); // error C2664. This is as expected. ^ main.cpp:2:6: error: in passing argument 1 of ''void f2(char&)'' void f2(char&); ^ main.cpp:12:12: error: invalid initialization of non-const reference of type ''A&'' from an rvalue of type ''A'' f4(f3()); // OK! Why??? ^ main.cpp:7:6: error: in passing argument 1 of ''void f4(A&)'' void f4(A&);