473,398 Members | 2,165 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,398 software developers and data experts.

want to write outstream operator <<, arguments are more than two different types...

Hello, C++ experts,

I am writing a Log class something like below.

================= c++ source code ========================

class Log {
public:
Log();
Log(string _filename);
~Log();

public:
template<typename paramT>
void operator<<(const paramT& param)
{
ofstream outfile;
char argument[256] = {0};
sprintf (argument, "%s", filename.c_str());
outfile.open(argument, ios::app);

outfile << param;
};

private:
string filename;
};


================= c++ source code ========================

and I use above like

================= c++ source code ========================
Log log("Process.txt");

vector<Edge*>::iterator ei;
for ( ei = edgeSet.begin(); ei != edgeSet.end(); ++ei )
{
log << (*ei)->GetEdgeID(); // => works, for sure...

log << "Edge ID: " << (*ei)->GetEdgeID() << " "; // => fails..
}
================= c++ source code ========================

As you may see, ( log << (*ei)->GetEdgeID(); ) works fine,

but, ( log << "Edge ID: " << (*ei)->GetEdgeID() << " "; ) just fails...

clearly because the operator must deal with more than one different output

types like string, integer, and many other data types...

What can be the best measures for this?
Nov 10 '09 #1

✓ answered by RRick

A simple way to implement a Log class is by putting the ofstream object in the Log class. This is an HAS-A relation where the Log class has an ofstream object.

It would look something like

Expand|Select|Wrap|Line Numbers
  1. class Log
  2. {
  3. public:
  4.     Log( const string & fileName);
  5.     void write( const string & message);
  6. private:
  7.     ofstream stream_;
  8. };
The Log constructor would initialize ofstream with the file name.

The write method would write a message to the file. The write method could also add extra info like the date and time to the log along with the message.

This allows you to put the different tasks in only the places where they are needed. For example, write is not interested in opening an ofstream and the constructor is not interested in writing things out. This separation of functionality is one of the things that gives objects great versatility.

5 2943
weaknessforcats
9,208 Expert Mod 8TB
Your operator<< returns void so there's no stream for << (*ei)->GetEdgeID() . The operator<< needs to return an ostream& (not an ostream).

Expand|Select|Wrap|Line Numbers
  1. log << "Edge ID: " << (*ei)->GetEdgeID() << " "; // => fails..

Also, what's the array and the sprintf all about? This is C++ and not C.

Expand|Select|Wrap|Line Numbers
  1. template<typename paramT>
  2. void operator<<(const paramT& param)
  3. {
  4. ofstream outfile;
  5. char argument[256] = {0};
  6. sprintf (argument, "%s", filename.c_str());
  7. outfile.open(argument, ios::app);
  8.  
  9. outfile << param;
  10. }; 
The ofstream should have been created in the constructor that takes a string& as an argument. You might write that constrcutor. Note that filename.c_str() is a C string so you still don't need the array or the sprintf.


That will reduce your operator<< to:

Expand|Select|Wrap|Line Numbers
  1. template<typename paramT>
  2. void operator<<(const paramT& param)
  3. {
  4.     outfile << param;
  5. }; 
which is now just calling the operator<< of param.

Therefore, your log class is unnecessary.

Lastly, operator<< cannot be a member function. The first argument of operator<< has to be an ostream& and if it is a member funciton, the compiler will add a first argument of this. That gives the operator<< a this argument, an ostream& argument, and the param argument. Now you die compiling an operator<< with 3 arguments. Research friend functions.
Nov 10 '09 #2
Thank you for your kind answer.

My intention was to write an ostream operator "<<" data stream

following which could be written to a log file whose name is constructed

when Log class is being instantiated like Log log("test.txt");

That was why there are codes like

==================================
ofstream outfile;
char argument[256] = {0};
sprintf (argument, "%s", filename.c_str());
outfile.open(argument, ios::app);
==================================

was required.


But, as you suggested, the operator returns void,

since I changed the meaning of "<<" into the operator for ofstream

inside the method. That is, data stream following "<<" are written to

file(s), making it not necessary to return ostream& object.


Let me research sometime, and if I come up with an answer, I will

report here.
Nov 10 '09 #3
Lastly, operator<< cannot be a member function. The first argument of operator<< has to be an ostream& and if it is a member funciton, the compiler will add a first argument of this. That gives the operator<< a this argument, an ostream& argument, and the param argument. Now you die compiling an operator<< with 3 arguments. Research friend functions.
It looks like I read relevant part in Stroustrup's book. Thank for the tip.
Nov 10 '09 #4
I work as a natural language processing system designer without

computer science major background( I majored in English literatures and

linguistics..). So my problem would have seemed a little bit foolish to

many of you. At any rate...

After thinking for a while, I realize that "Log class" was not necessary

to attain what was shown above. Simply using fstream object may

fulfill my needs at this moment as following.

Expand|Select|Wrap|Line Numbers
  1. ofstream outfile;
  2. outfile.open("log.txt", ios::out);
  3. :
  4.     outfile << "future cost from node["<< (*i)->GetNodeID() << "] to [" 
  5.     << (*j)->GetNodeID() << "] :" << dist[(*i)->GetNodeID()][(*j)->GetNodeID()] << endl;
  6. :
  7. outfile.close();
  8.  
I needed the above bit to implement Floyd-Warshall all pair shortest path
algorithm and I thought Log class would be convenient to record some
verbose information during process.

Thank you.
Nov 12 '09 #5
RRick
463 Expert 256MB
A simple way to implement a Log class is by putting the ofstream object in the Log class. This is an HAS-A relation where the Log class has an ofstream object.

It would look something like

Expand|Select|Wrap|Line Numbers
  1. class Log
  2. {
  3. public:
  4.     Log( const string & fileName);
  5.     void write( const string & message);
  6. private:
  7.     ofstream stream_;
  8. };
The Log constructor would initialize ofstream with the file name.

The write method would write a message to the file. The write method could also add extra info like the date and time to the log along with the message.

This allows you to put the different tasks in only the places where they are needed. For example, write is not interested in opening an ofstream and the constructor is not interested in writing things out. This separation of functionality is one of the things that gives objects great versatility.
Nov 12 '09 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: ma740988 | last post by:
Consider #include <iostream> #include <string> #include <map> using namespace std; struct dstream // data_stream class {
3
by: Sensei | last post by:
Hi. I have a problem with a C++ code I can't resolve, or better, I can't see what the problem should be! Here's an excerpt of the incriminated code: === bspalgo.cpp // THAT'S THE BAD...
14
by: lutorm | last post by:
Hi everyone, I'm trying to use istream_iterators to read a file consisting of pairs of numbers. To do this, I wrote the following: #include <fstream> #include <vector> #include <iterator> ...
8
by: jois.de.vivre | last post by:
Hi, I'm having some trouble overloading the << operator. I have the following, very simple code: #include <iostream> using namespace std; class test { private: int val;
3
by: Carlo Capelli | last post by:
I found a change in the following code, that behaved correctly in VC++ 6. #include <strstream> using namespace std; void main() { char x; ostrstream(x, 100) << "pippo" << "pluto" << ends;...
25
by: Steve Richter | last post by:
is it possible to overload the << operator in c# similar to the way it is done in c++ ? MyTable table = new MyTable( ) ; MyTableRow row = new MyTableRow( ) ; row << new MyTableCell( "cell1 text...
40
by: Neo The One | last post by:
I think C# is forcing us to write more code by enforcing a rule that can be summarized as 'A local variable must be assgined *explicitly* before reading its value.' If you are interested in what...
0
by: RC | last post by:
What would limit the amount of data that can be written to disk in an ASP.NET Web application? I've looked in the application's Web.config and don't see anything that would explain it. Here's...
5
by: krzysztof.konopko | last post by:
I cannot compile the code which defines a std::map type consisting of built in types and operator<< overload for std::map::value_type. See the code below - I attach a full example. Note: if I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
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,...

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.