2009-09-07 7 views
0

Je SURCHARGE opérateur < < pour mettre en œuvre un flux comme interface pour une classe:VC6 et erreur modèle

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

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

La version du modèle ne peut pas compiler avec « erreur fatale C1001: ERREUR INTERNE COMPILER (fichier compilateur « MSC1 .cpp ', ligne 1794) ". Les fonctions non-template se compilent toutes correctement.

Est-ce dû à des manques de VC6 lors de la manipulation des templates et y a-t-il un moyen de contourner ce problème?

Merci, Patrick

EDIT:

la classe complète est:

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

Le problème se produit avec la surcharge de fonction de l'opérateur < < qui est utilisé pour permettre à écrire() à être utilisé comme un manipulateur de flux:

CAudit audit 
audit << "Billy" << write; 
+0

Puis-je voir le code source complet? – adatapost

Répondre

1

Cette surcharge du modèle pour les pointeurs de fonction est sûrement trop pour bon vieux Visual Studio 6. Pour contourner ce problème, vous pouvez définir un type pour votre opérateur de manipulateur et de surcharge < < pour ce type. Voici un 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; 
} 
+0

Je n'aime pas avoir à initialiser le membre statique, mais cela fonctionne, merci – Patrick

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

EDIT:

#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; 
} 
+0

Non, cela ne fait pas de différence – Patrick

0

Le problème ne semble pas être dans le extrait de code que vous avez publié. Ce programme fonctionne très bien:

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

Pourriez-vous poster plus de code?

1

Le type d'erreur ressemble certainement au type de plantage causé par l'implémentation des modèles de pré-norme VC6. Le meilleur conseil est bien sûr de mettre à niveau vers VC7.0, 7.1, 8.0, 9.0 ou le bêta de 10. Pour comparer cela aux versions de Windows, il utilise toujours Windows 98 quand Me, 2000, XP, Vista et 7 sont disponibles.

Cela dit, vous pouvez simplifier la recherche beaucoup par une astuce simple:

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

L'espoir est que la première recherche de operator<< trouve le modèle de membre unique. Les autres candidats operator<< sont non-membres pour d'autres classes et built-ins. Ils devraient être sans ambiguïté pire que ce modèle. La deuxième recherche à l'intérieur de votre operator doit seulement traiter avec CAudit membres appelés print.

+0

Cela semble juste, mais ne pouvait pas le faire fonctionner ... – Patrick

Questions connexes