Frage

Ich verbrachte einige Zeit, um alle uninfluent Code zu entfernen, und hier ist mein Problem.

--- --- 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;
}

Und das ist die Ausgabedatei nach dem Aufbau mit cl und Optionen /D "WIN32" /D "_UNICODE" /D "UNICODE" und läuft

--- --- test.txt

00414114test

Im Grunde, was passiert ist, dass der erste operator<< Anruf in main an die Element-Methode gebunden ist

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

während die zweite ist (richtig) gebunden

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

also einen anderen Ausgang zu geben.

Dies geschieht nicht, wenn ich eine der folgenden Bedingungen tun:

        
  • Inline File::CreateOutput
  •     
  • Ändern DataOutput mit einem nicht-Vorlage eines mit Element=char
  •     
  • Add *output; vor dem ersten operator<< Anruf

Am i korrigieren diese einen unerwünschten Compiler Verhalten bei der Prüfung?

Gibt es eine Erklärung dafür?

Oh, und ich bin mit VC 7 zur Zeit diesen vereinfachten Code zu testen, aber ich habe den ursprünglichen Code in VC9 und VC8 versucht, und das gleiche passiert.

Jede Hilfe oder sogar ein Hinweis ist willkommen

War es hilfreich?

Lösung

Sieht aus wie ein Compiler-Fehler. Sie könnten mit den neuesten VC-Compiler versuchen wollen (die im Moment ist VC10 Beta2), und wenn es nicht fixiert ist, folgen mit dem VC-Team (Sie erhalten eine komplette in sich geschlossene Repo müssen). Wenn es festgelegt ist, sollten Sie nur die Arbeit nutzen um dich gefunden und mit Ihrem Leben weitergehen.

Andere Tipps

Es ist ein Compiler Fehler (nicht sieht genauso aus wie ein), da es unterschiedliche Anruf Bindungen für die beiden identischen Aussagen erzeugt

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

Doch die Compiler innerhalb seiner Rechte ist , dies zu tun, da Sie

    void main()

Das bedeutet, dass dies kein gültiges C ++ Programm (void main ist nicht erlaubt in C entweder, und es hat nie gültig gewesen in C oder C ++). So wurden Sie laufen das Ergebnis der Code ungültig Quelle kompilieren. Das Ergebnis, dass kann alles sein.

Die Tatsache, dass die Visual C ++ Compiler nicht diagnose void main ist nur ein anderer Compiler Bug .

Veränderung

* Dataoutput Ausgang (file.CreateOutput (false false));

* Dataoutput output = file.CreateOutput (false, false); und es könnte funktionieren. Aber machen dies zu einem vernünftigen lib Funktion Sie müssen nicht aufräumen, nachdem Sie sollten keinen Zeiger, sondern ein tatsächliches Objekt zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top