visual studio reparar paquetes ingles idioma espaƱol error descargar community c++ visual-studio-2015 language-lawyer

studio - Posible error en el manejo de la palabra clave `default` en VS2015 C++



visual studio 2015 paquetes (1)

Mientras probaba el compilador VS2015 C ++, encontré un error extraño con la palabra clave default . Si lo hago:

struct Dummy { Dummy() = default; Dummy(const Dummy &) = delete; }; int main() { const Dummy& ref = Dummy(); return 0; }

yo obtengo

error C2280: ''Dummy :: Dummy (const Dummy &)'': intentando hacer referencia a una función eliminada
nota: ver declaración de ''Dummy :: Dummy''

Pero si uso un constructor vacío

struct Dummy { Dummy() {} Dummy(const Dummy &) = delete; }; int main() { const Dummy& ref = Dummy(); return 0; }

El código compila. Ejecutar el primer ejemplo con g++ o clang no produce ningún error.

¿Por qué utilizar el constructor predeterminado con VS2015 intenta usar el constructor de copia donde no lo hace en g ++ o clang?


Definitivamente es un error en VS 2015.

En C ++ 11, la asignación de una referencia temporal a una constante no debe llamar al constructor de copia, pero VS 2015 lo hace.

Puedes comprobarlo con

#include <iostream> struct Dummy { Dummy() = default; Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; } void test() const { std::cout << "test" << std::endl; } }; int main() { const Dummy& ref = Dummy(); ref.test(); return 0; }

compilado en VS 2013, 2015, gcc y clang. Solo VS (cualquier versión) llama al constructor de copia, si el constructor de la clase se define como = default .

Creo que el compiiler VS aún en 2015 usa erróneamente las antiguas reglas estándar de C ++ 03 para esto (8.5.3.5 de C ++ 03):

Si la expresión de inicialización es un rvalor, con T2 un tipo de clase, y "cv1 T1" es compatible con "cv2 T2", la referencia se enlaza de una de las siguientes maneras (la opción está definida por la implementación):

- La referencia está vinculada al objeto representado por el valor r (ver 3.10) o a un subobjeto dentro de ese objeto.

- Se crea un temporal de tipo "cv1 T2" [sic], y se llama a un constructor para copiar todo el objeto rvalue en el temporal. La referencia está vinculada a lo temporal o a un subobjeto dentro de lo temporal.

El constructor que se usaría para hacer la copia será llamable, ya sea que la copia se haga o no.

Los desarrolladores de VS eligieron la segunda vía. Corrigieron esto para el constructor vacío definido por el usuario ( {} ), pero se olvidaron de hacer esto para los constructores predeterminados ( = default ).

PD. Error en MS Connect (por favor vote)