By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,778 Members | 1,957 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,778 IT Pros & Developers. It's quick & easy.

Accepting manipulators

P: n/a
What do I need to make this work?

#include <iostream>
#include <fstream>

using namespace std;

struct LoggedCout {
ofstream file;
LoggedCout(const char* name) : file(name, ios::app) {}
template<class T>
LoggedCout& operator<<(const T& t)
{ cout << t; file << t; return *this; }
};

LoggedCout lout("flushtest.txt");

int main() {
lout << "output";
lout << flush;
// no match for 'operator<<' in 'lout << std::flush'
{ char c; cin >> c; }
return 0;
}
Martin

--
Quidquid latine scriptum sit, altum viditur.
Jun 14 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Martin Eisenberg wrote:
What do I need to make this work?

#include <iostream>
#include <fstream>

using namespace std;

struct LoggedCout {
ofstream file;
LoggedCout(const char* name) : file(name, ios::app) {}
template<class T>
LoggedCout& operator<<(const T& t)
{ cout << t; file << t; return *this; }
};

LoggedCout lout("flushtest.txt");

int main() {
lout << "output";
lout << flush;
// no match for 'operator<<' in 'lout << std::flush'
{ char c; cin >> c; }
return 0;
}


Was it you who asked a similar question about 'std::endl' yesterday?
If it was, why do you think it's different with 'flush'? It's just
another function pointer when used liek that in an expression.
If it wasn't, look in the archives for yesterday's postings here.
Please don't use this newsgroup as a write-only medium. Read it
before posting. Use Google Groups to read it beyond what your ISP's
news server retains.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '06 #2

P: n/a
Martin Eisenberg wrote:
What do I need to make this work?

#include <iostream>
#include <fstream>

using namespace std;

struct LoggedCout {
ofstream file;
LoggedCout(const char* name) : file(name, ios::app) {}
template<class T>
LoggedCout& operator<<(const T& t)
{ cout << t; file << t; return *this; }
};
Add this to your class:

typedef ostream&(*IOManip)(ostream&);
LoggedCout& operator<<( const IOManip iomanip )
{
cout << iomanip;
file << iomanip;
return *this;
}

Or better, consider making it a non-member function since the whole
thing is public anyway.

LoggedCout lout("flushtest.txt");

int main() {
lout << "output";
lout << flush;
// no match for 'operator<<' in 'lout << std::flush'
{ char c; cin >> c; }
return 0;
} [...] --
Quidquid latine scriptum sit, altum viditur.


Sic, sed nemo id intelleget.

Cheers! --M

Jun 14 '06 #3

P: n/a
mlimber wrote:
Martin Eisenberg wrote:

struct LoggedCout {
ofstream file;
LoggedCout(const char* name) : file(name, ios::app) {}
template<class T>
LoggedCout& operator<<(const T& t)
{ cout << t; file << t; return *this; }
};


Add this to your class:

typedef ostream&(*IOManip)(ostream&);
LoggedCout& operator<<( const IOManip iomanip )
{
cout << iomanip;
file << iomanip;
return *this;
}


Thanks! You're right, Victor, I should have seen that endl thread.
Let me change the question: why is T in my code not deduced as
something like IOManip above? Shouldn't it work as per 14.8.2/3?
Martin

--
In the Wacky Protestor's return, he hijacks the popular
children's TV show, "Mr. Funky's Wild Time", and uses it
to control the hearts and minds of every child watching.
-- http://www.bibleman.com/bibleman/store.jsp
Jun 14 '06 #4

P: n/a
Martin Eisenberg wrote:
[..]
Let me change the question: why is T in my code not deduced as
something like IOManip above? Shouldn't it work as per 14.8.2/3?


You supply a pointer to function. What would you expect T to be?

Have you tried changing the argument to 'T' instead of 'const T&'?

Notice that 'IOManip' is not passed by reference.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '06 #5

P: n/a
Victor Bazarov wrote:
Martin Eisenberg wrote:

Let me change the question: why is T in my code not deduced as
something like IOManip above? Shouldn't it work as per 14.8.2/3?


You supply a pointer to function. What would you expect T to be?


Actually, I just realized that "flush" does not name a single entity
so there's no way to deduce anything at all in the context in
question. Right?
Martin

--
Sphinx of black quartz, judge my vow!
--David Lemon
Jun 14 '06 #6

P: n/a
Martin Eisenberg wrote:
Victor Bazarov wrote:
Martin Eisenberg wrote:

Let me change the question: why is T in my code not deduced as
something like IOManip above? Shouldn't it work as per 14.8.2/3?


You supply a pointer to function. What would you expect T to be?


Actually, I just realized that "flush" does not name a single entity
so there's no way to deduce anything at all in the context in
question. Right?


Probably.

'std::flush' is a template. 'flush' also is an 'std::basic_ostream'
member function. 'std::basic_ostream' declares at least three overloaded
operator << functions that take function pointers. As soon as you write
'flush' there, the compiler tries to understand which 'flush' you mean.
Most likely it finds the 'std::flush' template and tries to see if it
can figure out that template's arguments. In fact, it has to try the
same template arguments as the 'basic_ostream' has. It succeeds, AFAICT.

I am not sure my explanation makes sense. Josuttis probably has a better
one in his Standard Library book.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.