[C++] call naar std::setw afvangen in class

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-09 16:51

LauPro

Prof Mierenneuke®

Topicstarter
Ik ben bezig met een soort debug class. Deze class kan de output sturen naar console maar ook naar een file of streamen over het netwerk. Het is een beetje afgekeken van qDebug().

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <iomanip>

class XDebug {

public:
    enum messageType { DebugMsg,WarningMsg,CriticalMsg };
    
    inline XDebug(messageType t) : stream(new Stream(t)) {}
    inline ~XDebug() { stream->os << std::endl; } 
    
    inline XDebug &maybeSpace() { if (stream->space) stream->os << " "; return *this; }
    
    inline XDebug &operator<<(const char *t) { stream->os << t; return maybeSpace(); }  
    inline XDebug &operator<<(std::string t) { stream->os << t; return maybeSpace(); }  

    inline XDebug &operator<<(struct _Setw t) { stream->os << t; return maybeSpace(); } 
    
private:
    struct Stream {
        Stream(messageType t) : os(std::cout), type(t), space(true) {}
        std::ostream &os;
        messageType type;
        bool space;
    } *stream;
};

inline XDebug xDebug() { return XDebug(XDebug::DebugMsg); }
Vervolgens ga ik te werk:
C++:
1
xDebug() << std::setw(10) << "10" << "Hallo"
Dan krijg ik:
code:
1
main.cpp:134: error: no match for &#8216;operator<<&#8217; in &#8216;xDebug()() << std::setw(10)&#8217;
Hoe kan ik std::setw universeel (dus portable) laten zijn op mijn eigen xDebug object. Ik heb in de header iomanip gekeken en daar heeft men een wrapper gebouwd die van std::ostream.width() aan roept. Ik vrees dat ik ook een eigen wrapper moet maken :? .

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

C++:
1
2
3
4
inline operator std::ostream&()
{
  return stream->os;
}

En dan gooi je ook beter je operator<< weg. Als je dingen wil overriden, toch beter niet, maar alles wat je via std::ostream& doet override je automatisch niet.

[ Voor 33% gewijzigd door H!GHGuY op 09-10-2011 15:28 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

mss een functie:

template<typename T>
XDebug &operator <<(T t) { stream->os << t; return maybeSpace(); }

ipv alle andere?

-niks-


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik zou voor de laatste oplossing gaan. Een implicit conversion operator kan je nogal wat kopzorgen bezorgen.

Overigens, je maybeSpace() zou weleens roet in het eten kunnen gooien voor manipulators die maar voor 1 invoer geldig zijn, en het maakt je spatie natuurlijk ook ineens breder bij een setw()

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Tja, de nette oplossing is om zoiets via een std::streambuf-derived class te doen. Dan kun je std::ostream functionaliteit blijven gebruiken.

Onderliggend hier is het probleem dat het type van `std::setw(int)` niet gespecificeerd is. Het enige wat je van dat type weet is dat er een bijbehorende `ostream& operator<<(ostream& os, ?)` is. XDebug is geen ostream, dus die operator<< gaat jou niet helpen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 19-09 16:51

LauPro

Prof Mierenneuke®

Topicstarter
Ik heb nu zelf even een struct op touw gezet voor mijn eigen setw-functie. De template-implementatie heb ik er ook in zitten alleen had ik ivm de complexiteit even weggelaten.

De formattering van de debugging is niet zo heel kritisch. Maar ik wil wel mooie, overzichtelijke lijstjes kunnen maken. Dus ik denk dat het risico met maybeSpace() wel mee valt. Ik heb wel meegemaakt dat er her en der soms extra spaties komen inderdaad. Maar tussen waarden moeten altijd spaties zitten. En anders is het een kwestie van alles in een stringbuffer zetten en dan naar de debug gooien.

Verder is het denk ik handig om niet direct de std::streambuf te deriven, dit omdat ik wil dat ik de output ook over netwerk kan versturen. En al hoewel alles een file is is het volgens mij nog niet zo makkelijk om ostream op een socket aan te sluiten?

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als je de input wilt afvangen moet je juist een streambuf implementeren. In streambuf::overflow() en streambuf::sync() flush je de contents vervolgens naar je socket (dat zijn typisch ook de enige twee methods die je hoeft te overriden). Je streambuf kun je vervolgens in een willekeurige ostream hangen (desnoods in std::cout ;)).

[ Voor 16% gewijzigd door .oisyn op 11-10-2011 02:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1