Frage

Ich überlastete den Operator <<, um eine Stream -ähnliche Schnittstelle für eine Klasse zu implementieren:

template<typename T>
CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}

CAudit& operator << ( LPCSTR data ) {
    audittext << data;
    return *this;
}

Die Vorlagenversion kompiliert nicht mit "Fatal ERROR C1001: Interner Compiler -Fehler (Compiler -Datei 'MSC1.cpp', Zeile 1794)". Nicht-Template-Funktionen kompilieren alle korrekt.

Liegt dies an VC6S -Mängel beim Umgang mit Vorlagen und gibt es einen Weg?

Danke, Patrick

BEARBEITEN :

Die vollständige Klasse lautet:

class CAudit
{
public:    
/* TODO_DEBUG : doesn't build! 
template<typename T>
CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}*/

~CAudit() { write(); }//If anything available to audit write it here

CAudit& operator << ( LPCSTR data ) {
    audittext << data;
    return *this;
}

//overload the << operator to allow function ptrs on rhs, allows "audit << data << CAudit::write;"
CAudit& operator << (CAudit & (*func)(CAudit &))
{
    return func(*this);
}

void write() {
}

//write() is a manipulator type func, "audit << data << CAudit::write;" will call this function
static CAudit& write(CAudit& audit) { 
    audit.write();
    return audit; 
}

private:
std::stringstream audittext;
};

Das Problem tritt bei der Funktion Überladung des Operators << auf, mit dem Write () als Stream -Manipulator verwendet werden kann:

CAudit audit
audit << "Billy" << write;
War es hilfreich?

Lösung

Diese Überladung der Vorlage für Funktionszeiger ist sicherlich zu viel für ein gutes altes Visual Studio 6. Als Problemumgehung können Sie einen Typ für Ihren Manipulator und einen Überlastungsoperator für diesen Typ definieren. Hier ist ein Code:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <windows.h>

class CAudit {

    std::ostringstream audittext;
    void do_write() {}

public:
    ~CAudit() { do_write(); } 

    // types for manipulators
    struct Twrite {};

    // manipulators
    static Twrite write;

    // implementations of <<
    template<typename T>
        CAudit& operator <<  ( const T& data ) {
        audittext << data;
        return *this;
    }

    CAudit& operator <<  ( LPCSTR data ) {
        audittext << data;
        return *this;
    }

    CAudit& operator <<  ( Twrite& ) {
        do_write();
        return *this;
    }
};

// static member initialization
CAudit::Twrite CAudit::write;



int main(int argc, char* argv[])
{
    CAudit a;
    int i = 123;
    const char * s = "abc";

    a << i << s << CAudit::write;

    return 0;
}

Andere Tipps

Die Art des Fehlers sieht definitiv so aus, als würde die Art der Abstürze durch VC6-Vorlagen-Implementierung von Vorlagen verursacht.

Der beste Rat ist natürlich, auf VC7.0, 7.1, 8.0, 9.0 oder die Beta von 10 zu aktualisieren. Um dies mit Windows -Versionen zu vergleichen, verwendet es immer noch Windows 98, wenn ich, 2000, XP, Vista und 7 verfügbar sind.

Trotzdem können Sie die Lookup durch einen einfachen Trick erheblich vereinfachen:

class CAudit {
    template<typename T>
    CAudit& operator<<(T const& t) {
        this->print(t);
        return *this;
    }
private:
    void print(int);
    void print(LPCSTR);
    void print(CAudit & (*func)(CAudit &));
    template<typename T> print(T const&);
};

Die Hoffnung hier ist, dass die erste Suche von operator<< Findet die einzelne Mitgliedsvorlage. Das andere operator<< Kandidaten sind Nichtmitglieder für andere Klassen und Einbauten. Sie sollten eindeutig schlechter sein als diese Vorlage. Die zweite Suche in Ihrem operator muss sich nur umgehen mit CAudit Mitglieder angerufen print.

 template<typename T>
    CAudit& operator <<  (T data ) {
        audittext << data;
        return *this;
    }

BEARBEITEN:

#include <iostream>
using namespace std;

class CAudit{
public:
    CAudit(){}

    template< typename T >
    CAudit &operator<<(T arg);
    CAudit &operator<<(char s);
};

template< typename T>
void oldLog(T arg){
  cout << arg;
}

template< typename T >
CAudit &CAudit::operator<<(T arg){
    oldLog( arg );
    return *this;
}
CAudit &CAudit::operator<<(char arg){
    oldLog( arg );
    return *this;
}
int main(){

    CAudit e;
    e << "Hello";
    e << 'T';

 return 0;
}

Das Problem scheint nicht im Code -Snippet zu sein, den Sie gepostet haben. Dieses Programm funktioniert einwandfrei:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <windows.h>

class CAudit {

std::ostringstream audittext;

public:
std::string getAuditText() const { return audittext.str(); }

template<typename T>
    CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}


CAudit& operator <<  ( int data ) {
    audittext << data;
    return *this;
}

CAudit& operator << ( LPCSTR data ) {
audittext << data;
return *this;
}
};


int main(int argc, char* argv[])
{
CAudit a;
int i = 123;
const char * s = "abc";

a << i;
a << s;

std::cout << "audittext is: '" << a.getAuditText() << "'\n";
return 0;
}

Könnten Sie mehr Code posten?

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