VC elegir el operador << equivocado sobrecargar solamente en la primera llamada. ¿Error?
-
21-09-2019 - |
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 conElement=char
- Agregar
*output;
antes de la primera llamadaoperator<<
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
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.