Question on deriving from ostream

H

Hans De Winter

Hi,

I am really puzzled why my compiler does not accept the following code:-

--- CODE STARTS HERE ---
#include <iostream>
using namespace std;

class Foo
{
};

class Writer: public ostream
{
public:
Writer() : ostream(cout.rdbuf()) {}
Writer& operator<<(Foo&) {cout << "Hi"; return *this;}
};

int main(int argc, const char* argv[])
{
Foo f;
Writer w;

w << "Test"; // OK
w << f; // OK
w << '\t'; // OK
w << endl; // Not OK: Compiler complains about <unknown type>
return 0;
}
--- CODE STOPS HERE ---

Any hints? Many thanks in advance!
Hans
 
J

John Harrison

Hans De Winter said:
Hi,

I am really puzzled why my compiler does not accept the following code:-

--- CODE STARTS HERE ---
#include <iostream>
using namespace std;

class Foo
{
};

class Writer: public ostream
{
public:
Writer() : ostream(cout.rdbuf()) {}
Writer& operator<<(Foo&) {cout << "Hi"; return *this;}
};

int main(int argc, const char* argv[])
{
Foo f;
Writer w;

w << "Test"; // OK
w << f; // OK
w << '\t'; // OK
w << endl; // Not OK: Compiler complains about <unknown type>
return 0;
}
--- CODE STOPS HERE ---

Any hints? Many thanks in advance!
Hans

The operator<< that you want to be called is a member of ostream. Since you
have defined your own operator<< in a derived class, that operator hides the
operator in the base class. Try removing operator<< from Writer and the
fourth line will compile (but the second won't). The other operator<< that
you are successfully calling (for "Test" and '\t') are free functions, not
member functions, so aren't hidden by the operator<< in Writer.

Moral, don't derive from ostream, there are almost certainly better ways of
doing what you are trying to do, like deriving from streambuf.

john
 
N

Nick Hounsome

John Harrison said:
Hans De Winter said:
Hi,

I am really puzzled why my compiler does not accept the following code:-

--- CODE STARTS HERE ---
#include <iostream>
using namespace std;

class Foo
{
};

class Writer: public ostream
{
public:
Writer() : ostream(cout.rdbuf()) {}
Writer& operator<<(Foo&) {cout << "Hi"; return *this;}
};

int main(int argc, const char* argv[])
{
Foo f;
Writer w;

w << "Test"; // OK
w << f; // OK
w << '\t'; // OK
w << endl; // Not OK: Compiler complains about <unknown type>
return 0;
}
--- CODE STOPS HERE ---

Any hints? Many thanks in advance!
Hans

The operator<< that you want to be called is a member of ostream. Since you
have defined your own operator<< in a derived class, that operator hides the
operator in the base class. Try removing operator<< from Writer and the
fourth line will compile (but the second won't). The other operator<< that
you are successfully calling (for "Test" and '\t') are free functions, not
member functions, so aren't hidden by the operator<< in Writer.

better still just bring them into scope with a using declaration
 
Y

Yakov Lerner

Hello,

There are 3 ways to fix this
(1) You can do

endl(Writer);

instead of 'Writer << endl;'. This will compile & work.

(2) If you want that 'Writer << endl' work, add this inside class Writer:

Writer& operator<<(ostream&(*f)(ostream&)) { f(*this); return *this; }

With this definition, 'Writer << endl' will compile (see Stroustrup, 21.4.6)

(3) Don't derive from ostream. In order to define 'operator<<' for Foo,
you don't need to derive from ostream.

Jacob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,162
Messages
2,570,893
Members
47,432
Latest member
GTRNorbert

Latest Threads

Top