manipulateur de stream personnalisé pour la classe

J’essaie d’écrire une classe d’audit simple qui prend une entrée via l’opérateur << et écrit l'audit après avoir reçu un manipulateur personnalisé comme celui-ci:

class CAudit { public: //needs to be templated CAudit& operator << ( LPCSTR data ) { audittext << data; return *this; } //attempted manipulator static CAudit& write(CAudit& audit) { //write contents of audittext to audit and clear it return audit; } private: std::stringstream audittext; }; //to be used like CAudit audit; audit << "Data " << data << " received at " << time << CAudit::write; 

Je reconnais que l’opérateur surchargé dans mon code ne retourne pas d’object de stream, mais je me demandais s’il était encore possible d’utiliser un manipulateur comme la syntaxe. Actuellement, le compilateur voit le “<<" en tant qu'opérateur de décalage à droite binaire.

Merci pour toute consortingbution, Pasortingck

Pour que cela fonctionne, vous devez append la surcharge de l’opérateur << pour les fonctions, puis appeler la fonction à partir de celui-ci:

  class CAudit { //...other details here as in original question CAudit& operator << (CAudit & (*func)(CAudit &)) { return func(*this); } }; CAudit audit; audit << "some text" << CAudit::write; 

Opérateur de décalage binary et opérateur de stream est le même opérateur. Il est tout à fait légal de surcharger l’opérateur + pour votre classe d’écrire “Hello world” sur std :: cout (bien que ce soit une très mauvaise idée). De la même manière, les auteurs de normes C ++ ont décidé de surcharger l’opérateur << pour les flux en écriture dans le flux.
Vous n’avez pas écrit clairement quel est votre problème. Je suppose que c’est une erreur de compilation. Dans ce cas, la meilleure chose à faire est de citer le message d’erreur. Si je ne me trompe pas, le problème est que vous avez uniquement défini l’opérateur << pour LPCSTR, et que vous voulez ensuite que l'objet fonction fonctionne, du côté droit.
Vous utilisez le mot “manipulateur”, mais vous comprenez mal quelque chose. Le manipulateur pour un stream (stream de STL) est une fonction qui exécute certaines actions sur le stream sur lequel il est écrit. Et cela ne fonctionne que pour cette surcharge:

 ostream& operator<< (ostream& ( *pf )(ostream&)); 

qui prend une fonction et l'applique à un stream.
De même vous avez besoin de:

 CAudit& operator<< (CAudit& ( *pf )(CAudit& audit)) { return (*pf)(audit); } 

Cela ne serait-il pas

 class CAudit { public: template< typename T > CAudit& operator<<( const T& data ) { audittext << data; return *this; } class write {}; void operator<<( const write& data ) { /* whatever */ } private: std::stringstream audittext; }; 

fais ce que tu veux?

Je fais quelque chose de très similaire pour le traçage, mais j’utilise un ssortingngstream . Cela garantit que tous les operator << () tiers operator << () et les manipulateurs fonctionnent. J'utilise également le descripteur au lieu du manipulateur d'écriture client.

 class DebugStream { public: DebugStream(short level, const char * file, int line) { sstream << "L" << level << "\t" << file << "\t" << line << "\t"; } ~DebugStream() { write(sstream.str()); } std::ostream & stream() { return sstream; } private: std::stringstream sstream; DebugStream(const DebugStream &); DebugStream & operator=(const DebugStream &); }; 

Ceci est ensuite rendu disponible avec quelques macros:

 #define DBG_ERROR if (1<=dbg_level()) DebugStream(1, __FILE__, __LINE__).stream() #define DBG_INFO if (2<=dbg_level()) DebugStream(2, __FILE__, __LINE__).stream() 

Et le code utilise simplement les macros

 DBG_INFO << "print some debug information"; 

Vous n'avez pas besoin d'un manipulateur d'écriture spécifique pour vider les données dans le fichier journal. Lorsque l'object DebugStream anonyme est hors de scope (une fois que le contrôle a quitté la ligne), le contenu est automatiquement écrit.

Bien que j'évite généralement les macros dans ce cas, l'utilisation de l'instruction if signifie que vous n'avez pas à prendre en charge la construction de la ligne de trace, sauf si vous en avez réellement besoin.

Le ostream du stream() ostream via la méthode stream() permet à cela de fonctionner pour les fonctions membres globales, car les objects anonymes ne peuvent pas être transmis en tant que parameters de référence non const.