Pregunta

Me pasó algún tiempo eliminar todo el código uninfluent y aquí está mi problema.

--- --- file.h

#include <fstream>
#include <string>

template <typename Element>
class DataOutput : public std::basic_ofstream<Element>
{
public:
    DataOutput(const std::string &strPath, bool bAppend, bool bBinary)
    : std::basic_ofstream<Element>(
        strPath.c_str(),
        (bAppend ? ios_base::app : (ios_base::out | ios_base::trunc)) |
(bBinary ? ios_base::binary : 0))
    {
        if (is_open())
            clear();
    }

    ~DataOutput()
    {
        if (is_open())
            close();
    }
};


class File 
{
public:
    File(const std::string &strPath);

    DataOutput<char> *CreateOutput(bool bAppend, bool bBinary);
private:
    std::string m_strPath;
};

--- --- File.cpp

#include <File.h>

File::File(const std::string &strPath)
: m_strPath(strPath)
{
}

DataOutput<char> *File::CreateOutput(bool bAppend, bool bBinary)
{
    return new DataOutput<char>(m_strPath, bAppend, bBinary);
}

--- --- main.cpp

#include <File.h>

void main()
{
    File file("test.txt");

    DataOutput<char> *output(file.CreateOutput(false, false));

    *output << "test"; // Calls wrong overload
    *output << "test"; // Calls right overload!!!

    output->flush();
    delete output;
}

Y este es el archivo de salida después de la construcción con cl y opciones /D "WIN32" /D "_UNICODE" /D "UNICODE" y funcionando

--- --- test.txt

00414114test

Básicamente lo que ocurre es que la primera llamada operator<< en main está ligada al método de la barra

basic_ostream<char>& basic_ostream<char>::operator<<(
    const void *)

mientras que el segundo es (correctamente) obligado a

basic_ostream<char>& __cdecl operator<<(
    basic_ostream<char>&,
    const char *)

dando así una salida diferente.

Esto no sucede si no hago nada de lo siguiente:

        
  • En línea File::CreateOutput
  •     
  • Cambiar DataOutput con una plantilla no uno con Element=char
  •     
  • Agregar *output; antes de la primera llamada operator<<

Estoy en lo cierto al considerar este un comportamiento no deseado compilador?

¿Hay alguna explicación para esto?

Ah, y estoy usando VC7 en el momento de probar el código simplificado pero yo he probado el código original en VC9 y VC8 y lo mismo ocurría.

Cualquier ayuda o incluso una pista se aprecia

¿Fue útil?

Solución

Parece que un error del compilador. Es posible que desee probar con la última compilador de VC (que en este momento es VC10 beta 2), y si no es fijo, el seguimiento con el equipo de VC (necesitará un acuerdo de recompra completa contenida auto). Si se fija, sólo debe utilizar el trabajo en torno a que pueda encontrar y seguir adelante con su vida.

Otros consejos

Es un error del compilador (no sólo se parece a uno) ya que produce diferentes fijaciones de llamada para los dos estados idénticos

    *output << "test"; // Calls wrong overload
    *output << "test"; // Calls right overload!!!

Sin embargo, el compilador está en su derecho para hacer esto, ya que usted tiene

    void main()

lo que significa que este no es un programa válido C ++ (no está permitido void main en C o bien, y nunca ha sido válida en C o C ++). Por lo tanto, usted ha estado funcionando el resultado de la compilación de código fuente no válida. El resultado de eso puede ser cualquier cosa.

El hecho de que el compilador Visual C ++ hace void main no diagnostica es sólo otro error del compilador .

cambio

DataOutput * salida (file.CreateOutput (false, false));

a

DataOutput * salida = file.CreateOutput (false, false); y que podría funcionar. Pero para que esta función lib razonable que usted no tiene que limpiar después de que usted no debe devolver un puntero, pero un objeto real.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top