473,796 Members | 2,601 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Logging class and overloaded stream operators [question #2]

Hi everyone,

I asked another question regarding this same subject about a week ago. See
thread:

http://groups.google.fi/group/comp.l...0bae667a479add

So, the basic idea is to have a compact logger class which can be used like
the std::cout stream and add extra functionality to it (line numbering, some
output counters etc.).

The class should also accept the iostream manipulators, including special
manipulators in <iomanip>. How can I make the logging class handle all the
manipulators in the same way std::cout does?

If I compile the code (see below) which tries to use the manipulators with
the Logger class, I get the following error messages:
g++ example2.cpp


example2.cpp: In function `int main()':
example2.cpp:51 : error: no match for 'operator<<' in 'mainlog <<
std::setw(int)( )'
example2.cpp:22 : error: candidates are: Logger& Logger::operato r<<(const
char*)
example2.cpp:28 : error: Logger& Logger::operato r<<(double)
example2.cpp:52 : error: no match for 'operator<<' in '
(+(&mainlog)->Logger::operat or<<(" x = "))->Logger::operat or<<(x) <<
std::endl'
example2.cpp:22 : error: candidates are: Logger& Logger::operato r<<(const
char*)
example2.cpp:28 : error: Logger& Logger::operato r<<(double)
example2.cpp:53 : error: `precision' undeclared (first use this function)
example2.cpp:53 : error: (Each undeclared identifier is reported only once
for
each function it appears in.)
example2.cpp:54 : error: no match for 'operator<<' in '
(&mainlog)->Logger::operat or<<("x = ") << std::showpos'
example2.cpp:22 : error: candidates are: Logger& Logger::operato r<<(const
char*)
example2.cpp:28 : error: Logger& Logger::operato r<<(double)
Simplified example code:

------------------------------------
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

class Logger
{
public:
Logger(const char* filename = "program.lo g")
{
logfile = new fstream(filenam e, fstream::out);
}

~Logger()
{
logfile->close();
delete logfile;
}

Logger& operator<<(cons t char* msg)
{
*logfile << msg;
return *this;
}

Logger& operator<<(cons t double val)
{
*logfile << val;
return *this;
}

private:
fstream* logfile;
};

int main()
{
Logger mainlog;
double x = 12.34567;

// These work fine
cout << setw(20) << setfill('*') << setprecision(4) ;
cout << " x = " << x << endl;
cout.precision( 2);
cout << "x = " << showpos << scientific << x << endl;

mainlog << "x = " << x << "\n";

// These don't work
//mainlog << setw(20) << setfill('*') << setprecision(4) ;
//mainlog << " x = " << x << endl;
//mainlog.precisi on(2);
//mainlog << "x = " << showpos << scientific << x << endl;

return 0;
}
------------------------------------

Any comments/suggestions are again very welcome!

Riku

--
life, space, irc

Oct 25 '05 #1
5 2178
Riku Jarvinen wrote:
Hi everyone,

I asked another question regarding this same subject about a week ago. See
thread:

http://groups.google.fi/group/comp.l...0bae667a479add
So, the basic idea is to have a compact logger class which can be used
like the std::cout stream and add extra functionality to it (line
numbering, some output counters etc.).

The class should also accept the iostream manipulators, including special
manipulators in <iomanip>. How can I make the logging class handle all the
manipulators in the same way std::cout does?

If I compile the code (see below) which tries to use the manipulators with [snip]

Simplified example code:

------------------------------------
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

class Logger
{
public:
Logger(const char* filename = "program.lo g")
{
logfile = new fstream(filenam e, fstream::out);
}

~Logger()
{
logfile->close();
delete logfile;
}

Logger& operator<<(cons t char* msg)
{
*logfile << msg;
return *this;
}

Logger& operator<<(cons t double val)
{
*logfile << val;
return *this;
}
what about replacing all these by a template:

template < typename T >
Logger& operator<< ( T const & t ) {
*logfile << val;
return *this;
}

This should handle the manipulators, too. (not tested!)

private:
fstream* logfile;
};

int main()
{
Logger mainlog;
double x = 12.34567;

// These work fine
cout << setw(20) << setfill('*') << setprecision(4) ;
cout << " x = " << x << endl;
cout.precision( 2);
cout << "x = " << showpos << scientific << x << endl;

mainlog << "x = " << x << "\n";

// These don't work
//mainlog << setw(20) << setfill('*') << setprecision(4) ;
//mainlog << " x = " << x << endl;
//mainlog.precisi on(2);
//mainlog << "x = " << showpos << scientific << x << endl;

return 0;
}

Best

Kai-Uwe Bux

Oct 25 '05 #2
Kai-Uwe Bux wrote:

[code]

what about replacing all these by a template:

template < typename T >
Logger& operator<< ( T const & t ) {
*logfile << val;
return *this;
}

This should handle the manipulators, too. (not tested!)

I tried this typename template and it didn't seem to help in the manipulator
issue. I think I can add something like:

Logger& Logger::operato r<<(ios_base& (*pf)(ios_base& ))
{
*logfile << pf;
return *this;
}

but this works only with the manipulators in ios_base and, for example,
precision is a member function of ios_base, not a manipulator. Any thoughts?

Riku


Best

Kai-Uwe Bux


Oct 26 '05 #3
Riku Jarvinen wrote:
Kai-Uwe Bux wrote:

[code]

what about replacing all these by a template:

template < typename T >
Logger& operator<< ( T const & t ) {
*logfile << val;
return *this;
}

This should handle the manipulators, too. (not tested!)


I tried this typename template and it didn't seem to help in the
manipulator issue. I think I can add something like:


The only issue I see is the use of std::endl. Have a look at:
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

class Logger
{
public:
Logger(const char* filename = "program.lo g")
{
logfile = new fstream(filenam e, fstream::out);
}

~Logger()
{
logfile->close();
delete logfile;
}

template < typename T >
Logger& operator<<( T const & t )
{
*logfile << t;
return *this;
}

void precision ( unsigned long p ) {
*logfile << std::setprecisi on( p );
}

private:
fstream* logfile;
};

int main()
{
Logger mainlog;
double x = 12.34567;

// These work fine
cout << setw(20) << setfill('*') << setprecision(4) ;
cout << " x = " << x << endl;
cout.precision( 2);
cout << "x = " << showpos << scientific << x << endl;

mainlog << "x = " << x << "\n";
mainlog << setw(20) << setfill('*') << setprecision(4) ;
mainlog << " x = " << x << '\n';
mainlog.precisi on(2);
mainlog << "x = " << showpos << scientific;
mainlog << x << '\n';

return 0;
}

Logger& Logger::operato r<<(ios_base& (*pf)(ios_base& ))
{
*logfile << pf;
return *this;
}

but this works only with the manipulators in ios_base and, for example,
precision is a member function of ios_base, not a manipulator. Any
thoughts?


See above. However, I do not yet have an idea about how to deal with endl.

Best

Kai-Uwe Bux
Oct 26 '05 #4
Kai-Uwe Bux wrote:
Riku Jarvinen wrote:

I tried this typename template and it didn't seem to help in the
manipulator issue. I think I can add something like:
The only issue I see is the use of std::endl. Have a look at:


Ok, thanks!

I think I have to include separately every member function of std::ostream,
std::ios and std::ios_base in the Logger class if I want to make it exactly
like std::cout?

However, I do not yet have an idea about how to deal with endl.

Actually, this (and all the other basic operator<< manipulators) can be
handled with the following addition to the class:

Logger& Logger::operato r<<(ostream& (*pf)(ostream&) )
{
*logfile << pf;
return *this;
}
Riku


#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

class Logger
{
public:
Logger(const char* filename = "program.lo g")
{
logfile = new fstream(filenam e, fstream::out);
}

~Logger()
{
logfile->close();
delete logfile;
}

template < typename T >
Logger& operator<<( T const & t )
{
*logfile << t;
return *this;
}

void precision ( unsigned long p ) {
*logfile << std::setprecisi on( p );
}

private:
fstream* logfile;
};

int main()
{
Logger mainlog;
double x = 12.34567;

// These work fine
cout << setw(20) << setfill('*') << setprecision(4) ;
cout << " x = " << x << endl;
cout.precision( 2);
cout << "x = " << showpos << scientific << x << endl;

mainlog << "x = " << x << "\n";
mainlog << setw(20) << setfill('*') << setprecision(4) ;
mainlog << " x = " << x << '\n';
mainlog.precisi on(2);
mainlog << "x = " << showpos << scientific;
mainlog << x << '\n';

return 0;
}

Logger& Logger::operato r<<(ios_base& (*pf)(ios_base& ))
{
*logfile << pf;
return *this;
}

but this works only with the manipulators in ios_base and, for example,
precision is a member function of ios_base, not a manipulator. Any
thoughts?


See above. However, I do not yet have an idea about how to deal with endl.

Best

Kai-Uwe Bux


Oct 26 '05 #5
Hi!

Riku Jarvinen schrieb:
[...]

So, the basic idea is to have a compact logger class which can be used
like the std::cout stream and add extra functionality to it (line
numbering, some output counters etc.).
[...]

Any comments/suggestions are again very welcome!


You could implement a streambuf derived class and and build an ostream
class with it. This ostream then can be used like any other ostream (I
implemented a iostream wrapper for bzip2 library this way).

Thomas
Oct 26 '05 #6

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

Similar topics

4
11630
by: Luis | last post by:
Below is my project. My Code is done, but when I try to compile it, my IDE crahses (again). I fixed up all the things you guys said I should, except for some which would not meet the project requiremnts. here is my code. it compiles, but crashes winsioux. #ifndef MYSTRING_H #define MYSTRING_H #include <iostream>
1
3267
by: Sean W. Quinn | last post by:
Hey folks, I have a question regarding file handling, and the preservation of class structure. I have a class (and I will post snippets of code later in the post) with both primitive data structures (ints), and more complex data structures (strings and vectors) in it, and would like to write the entire class to a data file that could then be read back and loaded. However I'm having difficulty with this -- I found out (due to an...
6
2179
by: Chris Mantoulidis | last post by:
Forgive me if I'm wrong but I think there is something like an extra member scope in classes. for example: class abc { ostream & operator << (ostream &, const abc &); istream & operator >> (istream &, abc &); private:
4
1622
by: masood.iqbal | last post by:
Please help me with this doubt that I have regarding overloaded operators. Sometimes they are member functions and sometimes they are friends (e.g. see the code snippet from Stroustrup, Second Edition that I have posted to comp.sources.d). How do we decide which is more appropriate? Why are the overloaded "<<" and ">>" operators always friends? Also, what is an appropriate application for the overloaded function call operator?
7
6762
by: Riku Jarvinen | last post by:
Hello everyone, I have a logging class which writes program outputs to the logfile. The class works fine as long as only C++ native data types are considered. The problem is that I have a program with a bunch of classes which have the output stream operators << of their own. The overloaded operators work fine when inserted into the std:cout stream but I don't know how to make the logging class accept them. If I try to compile the...
13
2008
by: olanglois | last post by:
Hi, I am trying to derive a new class that will add new functions but no new data members and the base class has overloaded operators (+,-,+=,-=,etc...) returning either (Base &) or (const Base) depending on the operator: class Derived : public Base { };
2
4059
by: ZHENG Zhong | last post by:
Hi, I implemented a small logging library with the API like this: logger& log = log_manager::instance().get_logger("my_logger"); log.stream(DEBUG) << "this is a debug message" << std::endl; log.stream(INFO) << "this is an info message" << std::endl;
2
1360
by: Angus | last post by:
I want to setup a macro to log informational strings if eg INFOLOGGING is defined. So I created a macro which outputs informational strings to a log file. I want to have a #define which switches this option on or off. My problem is that I need to do a load of string processing to build up the informational string. Then the informational string is passed
2
8059
by: Russell Warren | last post by:
I was just setting up some logging in a make script and decided to give the built-in logging module a go, but I just found out that the base StreamHandler always puts a newline at the end of each log. There is a comment in the code that says "The record is then written to the stream with a trailing newline "... I guess there wasn't the feedback to drive the change. All I'm after is the ability to log things like... Compiling...
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9531
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10459
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10237
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9055
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7553
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5446
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4120
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.