visual tipos studio sintaxis pero muestra errores ejecuta dev compila c++ c++11 reference null language-lawyer

c++ - tipos - Comprueba si la referencia de flujo es NULL ya no se compila



tipos de errores en visual basic (3)

El código no compara la referencia con NULL , sino que compara el objeto de referencia con NULL . Las referencias no pueden ser NULL , y es imposible comparar la referencia con NULL .

Y

Este proyecto compilé i cuando lo usé hace mucho tiempo atrás con el antiguo gnu toolchain.

Porque el comportamiento cambió desde C ++ 11.

Antes de C ++ 11, std::ostream podría convertirse implícitamente a void* través del operador void * () , que devuelve un puntero nulo si se produce un error en la transmisión. Por lo tanto, la intención original del código es verificar si la transmisión no tiene errores.

Desde C ++ 11, la función de conversión se cambió al explicit operator bool() , que devuelve false si se produce un error. Tenga en cuenta que la función está declarada como explicit , lo que significa que la conversión implícita a bool no está permitida, por lo que el código no se compilará con C ++ 11 nuevamente porque std::ostream no se puede convertir a bool implícitamente (y luego se compara) con NULL (un literal entero)).

Con un compilador compatible con C ++ 11 puede cambiar el código a

if (m_stream) { m_stream.flush(); }

Tenga en cuenta que para las conversiones contextuales se consideran incluso las funciones de conversión explícitas. Para el código anterior, m_stream se convertirá a bool mediante explicit operator bool() , entonces el valor se usaría para la condición de if .

Estoy compilando un proyecto desactualizado con mis últimos compiladores gcc g ++, (versión> 6)

Hay una clase CodeWriter con una variable de referencia ostream .

class CodeWriter { //private: protected: ostream &m_stream; public: CodeWriter(ostream &stream):m_stream(stream){} ~CodeWriter(){ if(m_stream != NULL){ m_stream.flush(); } } };

La clase es bastante grande, así que solo incluí las variables y funciones relevantes.

Como puede ver, el destructor parece estar comparando la referencia con NULL . Este proyecto se compiló bien cuando lo usé hace mucho tiempo con el antiguo gnu toolchain.

Pero ahora está lanzando un error que dice que no hay un operator != coincidente operator != Para comparar ostream y long int .

¿Alguien puede explicar la razón detrás del cambio y cómo puedo solucionarlo?

Estaré encantado de proporcionar información adicional / incluir a toda la clase si es necesario.


Las clases de flujo tenían un operator void*() en una de las clases base en pre-C ++ 11. Por supuesto, el valor void* podría compararse con NULL .

En C ++ actual, en cambio, es un explicit operator bool() que funciona en el contexto de la sentencia if , pero no en una expresión general.

El uso de un void* fue para evitar algunas conversiones no deseadas de bool que ocurrían cuando no teníamos operadores explicit .


Las transmisiones siempre se pueden evaluar en un contexto booleano, así que simplemente cámbielo a:

if (m_stream) { m_stream.flush(); }

C ++ 11 hizo la conversión a bool explicit . Esto es equivalente a if (!m_stream.fail()) . Antes de C ++ 11, esta capacidad de comprobación a corto plazo se logra al proporcionar una conversión (implícita) a void* , por lo que su código anterior solía funcionar.

La razón por la que el código está verificando esto, en lugar de simplemente llamar a m_stream.flush(); directamente, es posible que la secuencia pueda tener excepciones habilitadas para fallas y que puedan lanzar, [actualizar:] pero, como señaló @Arne, la flush sí misma puede fallar y lanzar también. Si no hay excepciones, solo puede omitir la verificación booleana por completo. [/ Actualizar]