VC6- und Vorlagenfehler
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;
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?