473,325 Members | 2,860 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Own Variant of cout

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi people,

I want to create my own variant of a cout Object, so that I can use
different of those for debugging...

Like this class, but as a stream...

class Log
{
private:
static int system_debuglevel;
int debuglevel;
public:
Log( int dl ) : debuglevel(dl) { }
void logthis( const char * msg)
{
if ( debuglevel <= system_debuglevel ) printf("%s", msg);
}

}

So that I can create global objects like those :

Debug(5);
Info(4);
Warn(3);
Error(2);

and can then do Debug << "DEBUGMESSAGE" << endl; with every kind of
object that has a ostream& operator<<()..
So I could need some help with this, I have tried to derive the
logger from ostream, I have tried template functions, but nothing
works really good... the class should then do the output decision for
Debug << "String" << 5 << 4.5f << endl; correctly, but it always
outputs only String, or always 5 and 4.5 regardless whaat
system_debuglevel is set... I could need some help...

greets

Dennis

-----BEGIN PGP SIGNATURE-----
Version: PGP 7.0.1

iQA/AwUBP4VyFhL69PVFlLwmEQLhswCgtBt1938ibhAXIKdiRjEDan 1AYwsAn0Nq
UUT+Cq0VLMAq9pRd9twbtN0C
=fsht
-----END PGP SIGNATURE-----

Jul 19 '05 #1
13 3624
Hi Dennis,
| I want to create my own variant of a cout Object, so that I can use
| different of those for debugging...
|
| Like this class, but as a stream...
|
| class Log
| {
| private:
| static int system_debuglevel;
| int debuglevel;
| public:
| Log( int dl ) : debuglevel(dl) { }
| void logthis( const char * msg)
| {
| if ( debuglevel <= system_debuglevel ) printf("%s", msg);
| }
|
| }
....
| and can then do Debug << "DEBUGMESSAGE" << endl; with every kind of
| object that has a ostream& operator<<()..
| So I could need some help with this, I have tried to derive the
| logger from ostream, I have tried template functions, but nothing
| works really good... the class should then do the output decision for
| Debug << "String" << 5 << 4.5f << endl; correctly, but it always
| outputs only String, or always 5 and 4.5 regardless whaat
| system_debuglevel is set... I could need some help...

Try adding the following public member function to the Log class
as it is defined above:

template<typename T>
Log& operator<<(const T& param)
{
if ( debuglevel <= system_debuglevel )
cout << param;
return *this;
}

I would expect this to work.
If it doesn't, please let me know what the behavior is...
hth - Ivan
--
http://ivan.vecerina.com
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #2
Hi,

I think you should be able to derive a class from ostream but then you have
to correctly interface with the ostream buffers I think.

An easier way is to forget about the ostream and use the class you now have.
Then pull all the streaming functions into your class with a template memer
function (goes in the header of course)

class CEnd
{
};
extern CEnd End;

template<class T> CLog& opeartor<<( T Value )
{
if( DebugLevel < SystemDebugLevel ) cerr << Value;
}

template<> CLog& operator<<( CEnd& End )
{
cerr << endl;
}

.... Some more specializations if you want

I do this from the top of my head so I might have make a mistake somewhere.
Now you can use your code but should use End instead of endl

This is the way I do it in my programs.

Regards, Ron AF Greve
"Dennis Lubert" <lu****@sipoc.de> wrote in message
news:bm*************@news.t-online.com...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi people,

I want to create my own variant of a cout Object, so that I can use
different of those for debugging...

Like this class, but as a stream...

class Log
{
private:
static int system_debuglevel;
int debuglevel;
public:
Log( int dl ) : debuglevel(dl) { }
void logthis( const char * msg)
{
if ( debuglevel <= system_debuglevel ) printf("%s", msg);
}

}

So that I can create global objects like those :

Debug(5);
Info(4);
Warn(3);
Error(2);

and can then do Debug << "DEBUGMESSAGE" << endl; with every kind of
object that has a ostream& operator<<()..
So I could need some help with this, I have tried to derive the
logger from ostream, I have tried template functions, but nothing
works really good... the class should then do the output decision for
Debug << "String" << 5 << 4.5f << endl; correctly, but it always
outputs only String, or always 5 and 4.5 regardless whaat
system_debuglevel is set... I could need some help...

greets

Dennis

-----BEGIN PGP SIGNATURE-----
Version: PGP 7.0.1

iQA/AwUBP4VyFhL69PVFlLwmEQLhswCgtBt1938ibhAXIKdiRjEDan 1AYwsAn0Nq
UUT+Cq0VLMAq9pRd9twbtN0C
=fsht
-----END PGP SIGNATURE-----

Jul 19 '05 #3
Moonlit wrote:
Hi,

I think you should be able to derive a class from ostream but then you have
to correctly interface with the ostream buffers I think.

An easier way is to forget about the ostream and use the class you now have.
Then pull all the streaming functions into your class with a template memer
function (goes in the header of course)

class CEnd
{
};
extern CEnd End;

template<class T> CLog& opeartor<<( T Value )
{
if( DebugLevel < SystemDebugLevel ) cerr << Value;
}

template<> CLog& operator<<( CEnd& End )
{
cerr << endl;
}

... Some more specializations if you want

I do this from the top of my head so I might have make a mistake somewhere.
Now you can use your code but should use End instead of endl

This is the way I do it in my programs.

Regards, Ron AF Greve


1. Don't top-post. Top-posting is where you put your response "on top"
of the original post. Replies are either interspersed or appended
to the bottom. Please fix your newsreader.

2. See this link:
http://www.jelovic.com/articles/stupid_naming.htm

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 19 '05 #4


Dennis Lubert wrote:

So I could need some help with this, I have tried to derive the
logger from ostream,


This is often not what you want to do.
But instead you want to replace the stream's streambuffer.
Every stream object contains a streambuffer object.
While the stream object is repsonsible for formatting the output,
the streambuffer object is responsible for the actual data transfer.

Search for posts or web pages written by 'Dietmar Kuehl'.
He has written some posts on how to write such a beast.
eg. http://groups.yahoo.com/group/boost/message/2511

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #5
Just a couple comments on the code you posted...
"Moonlit" <al******@jupiter.universe> wrote in message
news:3f***********************@news.xs4all.nl...
| An easier way is to forget about the ostream and use the class you now
have.
| Then pull all the streaming functions into your class with a template
memer
| function (goes in the header of course)
|
| class CEnd
| {
| };
| extern CEnd End;
|
| template<class T> CLog& opeartor<<( T Value )

It might be better to use T const& instead of T as a parameter type,
to avoid creating an unnecessary intermediate copy of the passed value.

| {
| if( DebugLevel < SystemDebugLevel ) cerr << Value;
return *this; // was missing here
| }
|
| template<> CLog& operator<<( CEnd& End )
| {
| cerr << endl;
return *this; // was missing here
| }
|
| ... Some more specializations if you want
|
| I do this from the top of my head so I might have make a mistake
somewhere.
| Now you can use your code but should use End instead of endl

Note that it should be possible to support std::endl instead of
using your own dedicated class.

I believe a templated operator<< will accept manipulators such as std::endl.
And when a specialization is needed, the following should do:
CLog& operator<<(ostream& (*pf)(ostream&))
{
cerr << pf; // or: pf(cerr);
// ... specialized behavior here, if needed ...
return *this;
}

Like you, this is off the top of my head -- not tested right now.

Hope this helps,
Ivan
--
http://ivan.vecerina.com
Brainbench MVP for C++ <> http://www.brainbench.com
Jul 19 '05 #6
"Dennis Lubert" <lu****@sipoc.de> wrote:
So that I can create global objects like those :

Debug(5);
Info(4);
Warn(3);
Error(2);

and can then do Debug << "DEBUGMESSAGE" << endl; with every kind of
object that has a ostream& operator<<()..
.... and you want your output depending on some global resource
"system_debuglevel". Unfortunately, you didn't specify when this
resource is set up but, for my convenience, I assume it is set up
prior to the initialization of the stream objects. In this case,
the class derived from 'std::ostream' is actually extremely simple:

int system_debuglevel = 3;

struct logstream {
logstream(int level):
std::ostream(level <= system_debuglevel? std::cout.rdbuf(): 0) {
}
};

logstream Debug(5);
logstream Info(4);
logstream Warn(3);
logstream Error(2);

If the "system_debuglevel" can change or not initialized when the
stream objects are constructed, there are effectively two options:

- Set the "system_debuglevel" with a function which installs/removes
stream buffers from you log stream objects (in which case you don't
a class at all; well, actually there is no true need for a class in
the above code: you could make the decision for each initialization).

- If you want to modify "system_debuglevel" freely, without calling a
function, derive a class from 'std::streambuf' which does not buffer
the characters. This class would then swallow the characters when
the system's debug level is too low or send them on to 'std::cout's
debug level otherwise.

The first of these two approaches is much faster.
So I could need some help with this, I have tried to derive the
logger from ostream, I have tried template functions, but nothing
works really good...


That would be because you don't understand how the IOStream classes
work: there is no point in deriving from 'std::ostream' other than
setting the object up with some specifically constructed stream buffer.
If you want to change the logic how or where the stream dumps the
characters, you would change the stream buffer within.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
Jul 19 '05 #7

"Thomas Matthews" <Th**********************@sbcglobal.net> wrote in message
news:4M*****************@newssvr17.news.prodigy.co m...
Moonlit wrote:
Hi,

I think you should be able to derive a class from ostream but then you have to correctly interface with the ostream buffers I think.

An easier way is to forget about the ostream and use the class you now have. Then pull all the streaming functions into your class with a template memer function (goes in the header of course)

class CEnd
{
};
extern CEnd End;

template<class T> CLog& opeartor<<( T Value )
{
if( DebugLevel < SystemDebugLevel ) cerr << Value;
}

template<> CLog& operator<<( CEnd& End )
{
cerr << endl;
}

... Some more specializations if you want

I do this from the top of my head so I might have make a mistake somewhere. Now you can use your code but should use End instead of endl

This is the way I do it in my programs.

Regards, Ron AF Greve
1. Don't top-post. Top-posting is where you put your response "on top"
of the original post. Replies are either interspersed or appended
to the bottom. Please fix your newsreader.


Personally I like top posting.

Reason:

I already read the other posts in the thread so I only want to read the
stuff that's added. To prevent me from having to scroll down with every
post; TOPpost.

Now you might have a different opinion but please keep in mind that most of
us live in a free world where one can have is own opinion.
2. See this link:
http://www.jelovic.com/articles/stupid_naming.htm
Well it is fun to read. I like to use C<class> for my classes so I can use
<class> for the variables like
CLog Log
But everyone has its own preferences I guess. (and it is nice to see people
who are prepending everything with T so you know who is using microsoft or
borland compilers). (What I do while compiling with g++, I just add a C to
every class, sorry)


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book


For youre convenience I made this a bottom post ;-)

Regards, Ron AF Greve.
Jul 19 '05 #8

"Ivan Vecerina" <NONE_use_form@website_to_contact_me> wrote in message
news:3f********@news.swissonline.ch...
Just a couple comments on the code you posted...
"Moonlit" <al******@jupiter.universe> wrote in message
news:3f***********************@news.xs4all.nl...
| An easier way is to forget about the ostream and use the class you now
have.
| Then pull all the streaming functions into your class with a template
memer
| function (goes in the header of course)
|
| class CEnd
| {
| };
| extern CEnd End;
|
| template<class T> CLog& opeartor<<( T Value )

It might be better to use T const& instead of T as a parameter type,
to avoid creating an unnecessary intermediate copy of the passed value.
Absolutely right!

| {
| if( DebugLevel < SystemDebugLevel ) cerr << Value;
return *this; // was missing here
| }
|
| template<> CLog& operator<<( CEnd& End )
| {
| cerr << endl;
return *this; // was missing here
| }
|
| ... Some more specializations if you want
|
| I do this from the top of my head so I might have make a mistake
somewhere.
| Now you can use your code but should use End instead of endl

Note that it should be possible to support std::endl instead of
using your own dedicated class.

I believe a templated operator<< will accept manipulators such as std::endl. And when a specialization is needed, the following should do:
CLog& operator<<(ostream& (*pf)(ostream&))
{
cerr << pf; // or: pf(cerr);
// ... specialized behavior here, if needed ...
return *this;
}

Like you, this is off the top of my head -- not tested right now.
That would be much better, I will try this in my class, I didn't get it
working so I took the easy way out a long time ago. I will use your
suggestion since it is more convenient especaily when switching from Log to
cout as one sometimes do.

Thanks for your recommendations.

Regards, Ron AF Greve.
Hope this helps,
Ivan
--
http://ivan.vecerina.com
Brainbench MVP for C++ <> http://www.brainbench.com

Jul 19 '05 #9
Moonlit wrote:
For youre convenience I made this a bottom post ;-)

Regards, Ron AF Greve.


Its just easier if you bottom post, otherwise you get all the post
nazi's bleeting about it.

:)

Ryan

Jul 19 '05 #10
"Moonlit" <al******@jupiter.universe> writes:
"Thomas Matthews" <Th**********************@sbcglobal.net> wrote in message
news:4M*****************@newssvr17.news.prodigy.co m...
Moonlit wrote:
1. Don't top-post. Top-posting is where you put your response "on top"
of the original post. Replies are either interspersed or appended
to the bottom. Please fix your newsreader.


Personally I like top posting.

Reason:

I already read the other posts in the thread so I only want to read the
stuff that's added. To prevent me from having to scroll down with every
post; TOPpost.


That's just YOU - how about people who didn't read the previous post?
Apart from that: PLEASE learn to trim the messages you are replying to,
keeping only the important parts.
(Interistingly, in my experience most people who insist on top posting
also don't trim messages - but YMMV)

A: Top posting
Q: What's the most annoying thing on Usenet?

Enough said.

regards
frank
--
Frank Schmitt
4SC AG phone: +49 89 700763-0
e-mail: frankNO DOT SPAMschmitt AT 4sc DOT com
Jul 19 '05 #11
"Moonlit" <al******@jupiter.universe> wrote in message news:<3f***********************@news.xs4all.nl>...
1. Don't top-post. Top-posting is where you put your response "on top"
of the original post. Replies are either interspersed or appended
to the bottom. Please fix your newsreader.


Personally I like top posting.

Reason:

I already read the other posts in the thread so I only want to read the
stuff that's added. To prevent me from having to scroll down with every
post; TOPpost.


The need for excessive scrolling can be avoided by snipping the post
to which you are replying and keeping only enough for context.
Arguably, Thomas could have done that when he replied to you (although
he needed to keep some of your post for context for his class naming
link).

Although it doesn't affect me (since I am here courtesy of Google,
which seems to be several hours behind reality), I have seen pointed
out a number times that the nature of message propogation around the
world on usenet is such that you can't assume someone reading your
message has already read the message to which you are replying.

A complicated technical discussion, involving several successive
posts, is a lot easier to follow with unnecessary content snipped and
replies following or interleaved with the parts of the previous
message to which they apply.

Reason:

Personally I don't like top posting.

GJD
Jul 19 '05 #12
First of all, thanks for the many answers

"Dietmar Kuehl" <di***********@yahoo.com> schrieb im Newsbeitrag
news:5b**************************@posting.google.c om...
That would be because you don't understand how the IOStream classes
work: there is no point in deriving from 'std::ostream' other than
setting the object up with some specifically constructed stream buffer
I guess my problem from now on is this buffer... and I really don't fully
understand the streaming stuff
If you want to change the logic how or where the stream dumps the
characters, you would change the stream buffer within.


Could you give me a hint how to do this ??

I have written the following stuff so far. Somone asked for the
system_debuglevel. It MUST be changeable after the creation of the
debug-stream objects, and they must then behave according to the new one. I
would expect the following output from my main :

hello world 123 0.5\n
hello world 123 0.5\n

But what I get is :

hello world hello world

well, at least for the first string, it seems to work, that it reacts
according to the debuglevel, but where are the 123 and 0.5 and endl ??

Here is my program so far ( I use gcc 3.3 for compiling it )

#include <iostream>
using namespace std;

int system_debuglevel = 5;

class foo : public ostream
{
private:
int debuglevel;

public:
foo( int dl) : ostream(NULL), debuglevel(dl) {}
template <class T> ostream &operator<<(const T &data);
};

template <class T> ostream& foo::operator<<(const T &data) {

// cerr << __PRETTY_FUNCTION__ << std::endl;

if ( debuglevel <= system_debuglevel )
cout << data;

return *this;
}

int main(void) {
foo bar4(4);
foo bar5(5);
foo bar6(6);
bar4 << "hello world " << " " << 123 << " " << 0.5f << endl;
bar5 << "hello world " << " " << 123 << " " << 0.5f << endl;
bar6 << "hello world " << " " << 123 << " " << 0.5f << endl;

cout << endl;
return 0;
}

Jul 19 '05 #13
<veröffentlicht & per Mail versendet>

Dennis Lubert wrote:
"Dietmar Kuehl" <di***********@yahoo.com> schrieb:
I guess my problem from now on is this buffer... and I really don't fully
understand the streaming stuff
I have posted quite a few articles on how to create own stream buffers
over the years. Although rather aged by now, you can find an explanation
of this stuff if you look for IOStreams I have done at Konstanz (eg.
<http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/>).
If you want to change the logic how or where the stream dumps the
characters, you would change the stream buffer within.


Could you give me a hint how to do this ??


Sure. However, I have posted stuff like this often in the past. Actually
I'm quite sure that I have addressed this particular logging level stuff
before. As indicated in my previous answer, you could do a much better
job when the debug level is maintained via a function because in this
case you can simply set or clear a state bit or the stream buffer in the
respective stream objects: this is both easier and faster (and I think I
have even posted code for this before, too).

Here is my program so far ( I use gcc 3.3 for compiling it )
.... and it doesn't follow my advice given in my previous reply at all!
class foo : public ostream
{ [...] template <class T> ostream &operator<<(const T &data);
};


I'm positive that I have advised you *NOT* do anything like the above
(the exact statement read "there is no point in deriving from
'std::ostream' other than setting the object up with some specifically
constructed stream buffer).
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
Jul 19 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Matt Smith | last post by:
Hi, all. Just a quick question, when setting a COM process to read a value from a pre-defined register index, I think, I have to change the variable that the value will be returned to (as I have...
0
by: Matt Smith | last post by:
Hi, all. Just a quick question, when setting a COM process to read a value from a pre-defined register index, I think, I have to change the variable that the value will be returned to (as I have...
8
by: MLH | last post by:
A97 HELP shows the proper syntax for using Nz as Nz(variant) I'm wondering what to expect from potential past misuse I've made. For example, consider the following... Private Sub...
5
by: Torben Laursen | last post by:
Hi Can anyone show me how to convert between VARIANT and std::string and back, thanks! Torben ---
19
by: Jon Davis | last post by:
Hi guys! Just wanted to let you all know that I created a Variant structure, inspired by the old VB6 days. This is written in C#, but you can build a CLR/.NET class library assembly and reference...
0
by: sathya.krishnamurthy | last post by:
Hello Everybody I have an C++ COM DLL with the following implementation. __interface ICPM : IDispatch { HRESULT GlobalComputeClass ( VARIANT *inArr, double *pval); }
1
by: morten | last post by:
When i compile this code in VC71 or VC80 i get the following errors: The code is copy/paste from the boost.org tutorial. Please help! error C2039: 'begin' : is not a member of...
1
by: captainc | last post by:
I have C++ code to import a .tlb and use a .dll that has functions that return VARIANT types and accepts BSTRs (bstrings). I have seen that python has modules that can manipulate VARIANTs and BSTRs...
4
by: jainchar | last post by:
hello I am creating a VARIANT that stores a integer value of variable but variable is not initialize.In my code the variable are "r" and"c" where r and c are the value of row and column of a table.I...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.