error: 'std::ios_base& std::ios_base::operator=(const std::ios_base&)' is private

G

Geoffrey S. Knauth

It's been a while since I programmed in C++, and the language sure has
changed. Usually I can figure out why something no longer compiles, but
this time I'm stumped. A friend has a problem he hoped I could solve,
and I couldn't. Some code he's using, written in 1999, that compiled
fine in 1999, no longer does in 2006 with g++ 4.

This little bit of code:

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;
is_opened = 0;
}

produces quite a few errors, such as these:

simstream.c: In constructor 'SimS::SimS(std::eek:stream&)':
/usr/include/c++/4.0.0/ostream:360: error: 'std::basic_ostream<_CharT,
_Traits>::basic_ostream() [with _CharT = char, _Traits =
std::char_traits<char>]' is protected
simstream.c:17: error: within this context
/usr/include/c++/4.0.0/iosfwd: In member function 'std::basic_ios<char,
std::char_traits said:
::eek:perator=(const std::basic_ios<char, std::char_traits<char> >&)':
/usr/include/c++/4.0.0/bits/ios_base.h:782: error: 'std::ios_base&
std::ios_base::eek:perator=(const std::ios_base&)' is private
/usr/include/c++/4.0.0/iosfwd:55: error: within this context
/usr/include/c++/4.0.0/iosfwd: In member function
'std::basic_ostream<char, std::char_traits<char> >&
std::basic_ostream<char, std::char_traits<char> >::eek:perator=(const
std::basic_ostream<char, std::char_traits<char> >&)':
/usr/include/c++/4.0.0/iosfwd:64: warning: synthesized method
'std::basic_ios<char, std::char_traits<char> >& std::basic_ios<char,
std::char_traits<char> >::eek:perator=(const std::basic_ios<char,
std::char_traits<char> >&)' first required here
simstream.c: In constructor 'SimS::SimS(std::eek:stream&)':
simstream.c:20: warning: synthesized method 'std::basic_ostream<char,
std::char_traits<char> >& std::basic_ostream<char,
std::char_traits<char> >::eek:perator=(const std::basic_ostream<char,
std::char_traits<char> >&)' first required here
simstream.c: In copy constructor 'SimS::SimS(SimS&)':
/usr/include/c++/4.0.0/ostream:360: error: 'std::basic_ostream<_CharT,
_Traits>::basic_ostream() [with _CharT = char, _Traits =
std::char_traits<char>]' is protected

How can this be fixed?

Thanks.

--
Geoffrey S. Knauth | http://knauth.org/gsk

A little more background:

class SimS {
public:
SimS (ostream &s);
SimS (SimS& s);
SimS (const char* f);
~SimS (void);
void flush (void);
private:
int rc; // reference count
ofstream fp; // file pointer
ostream Stream; // stream
bool is_opened; // a file was opened
int attached (void) { return ++rc; }
int detached (void) { return --rc; }
friend class SimStream; // only SimStream accesses the
above
};

class SimStream {
public:
SimStream (ostream &s, char *p = NULL);
SimStream (SimStream& s, char *p = NULL);
SimStream (const char* f, char *p = NULL);
~SimStream (void);
bool reopen (SimStream& s, char* p = NULL);
bool reopen (const char* f, char* p = NULL);
void flush (void);
SimStream& operator= (SimStream& s);
SimStream& operator<< (const int i);
SimStream& operator<< (const unsigned int i);
SimStream& operator<< (const unsigned long int i);
SimStream& operator<< (const long int i);
SimStream& operator<< (const char* s);
SimStream& operator<< (const char c);
SimStream& operator<< (const float f);
SimStream& operator<< (const double d);
SimStream& operator<< (ostream& o(ostream&));
SimStream& put (char c) { return *this; }
void width (int i) { entry->Stream.width(i); }
void fill (char c) { entry->Stream.fill(c); }
void setf (unsigned long val, unsigned long mask) {
entry->Stream.setf( (ios_base::fmtflags)val,
(ios_base::fmtflags)mask); }
void precision (int i) { entry->Stream.precision(i); }
private:
SimS* entry;
char* prompt;
bool is_echoed; // the prompt was echoed
void attach (SimS* s);
void detach (void);
};
 
V

Victor Bazarov

Geoffrey said:
It's been a while since I programmed in C++, and the language sure has
changed.

Not that much.
> Usually I can figure out why something no longer compiles, but
this time I'm stumped. A friend has a problem he hoped I could solve,
and I couldn't. Some code he's using, written in 1999, that compiled
fine in 1999, no longer does in 2006 with g++ 4.

This little bit of code:

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;

You're not supposed to copy streams. If your class keeps a _reference_
to a stream as a member, _initialise_ it, don't assign it.
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;

Same story.
is_opened = 0;
}

[..]

V
 
J

Jacek Dziedzic

Geoffrey said:
It's been a while since I programmed in C++, and the language sure has
changed. Usually I can figure out why something no longer compiles, but
this time I'm stumped. A friend has a problem he hoped I could solve,
and I couldn't. Some code he's using, written in 1999, that compiled
fine in 1999, no longer does in 2006 with g++ 4.

This little bit of code:

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;
is_opened = 0;
}

produces quite a few errors, such as these:

Show how "Stream" is defined and what header files you
include. Posting a small _compilable_ chunk of code
that exhibits the behaviour is good.

- J.
 
B

Bob Hairgrove

This little bit of code:

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;
is_opened = 0;
}

produces quite a few errors, such as these:

[snip]

Some questions arise:

1. What headers are included? (Note: headers with a trailing "*.h" can
cause problems, especially WRT i/o-streams)
2. Where do you declare namespace std?
class SimS {
public:
// SimS (ostream &s);
That should be:
SimS (std::eek:stream &s);
// SimS (SimS& s);
That should probably be:
SimS (SimS const & s);
SimS (const char* f);
// ~SimS (void);
That should be:
~SimS ();
// void flush (void);
That should be:
void flush ();
private:
int rc; // reference count
// ofstream fp; // file pointer
That should be:
std::eek:fstream fp; // file pointer
ostream Stream; // stream
That should be:
std::eek:stream Stream; // stream
 
G

Geoffrey S. Knauth

Jacek Dziedzic said:
Show how "Stream" is defined and what header files you
include. Posting a small _compilable_ chunk of code
that exhibits the behaviour is good.

The two files causing problems are shown below. Thanks.

--
Geoffrey S. Knauth | http://knauth.org/gsk

--->-8 --- simstream.h -----------------------------------------8-<---
#ifndef __simstream_h__
#define __simstream_h__

#include <iostream>
#include <fstream>
using namespace std;

class SimS {
public:
SimS (ostream &s);
SimS (SimS& s);
SimS (const char* f);
~SimS (void);
void flush (void);
private:
int rc; // reference count
ofstream fp; // file pointer
ostream Stream; // stream
bool is_opened; // a file was opened
int attached (void) { return ++rc; }
int detached (void) { return --rc; }
friend class SimStream; // only SimStream accesses the
above
};

class SimStream {
public:
SimStream (ostream &s, char *p = NULL);
SimStream (SimStream& s, char *p = NULL);
SimStream (const char* f, char *p = NULL);
~SimStream (void);
bool reopen (SimStream& s, char* p = NULL);
bool reopen (const char* f, char* p = NULL);
void flush (void);
SimStream& operator= (SimStream& s);
SimStream& operator<< (const int i);
SimStream& operator<< (const unsigned int i);
SimStream& operator<< (const unsigned long int i);
SimStream& operator<< (const long int i);
SimStream& operator<< (const char* s);
SimStream& operator<< (const char c);
SimStream& operator<< (const float f);
SimStream& operator<< (const double d);
SimStream& operator<< (ostream& o(ostream&));
SimStream& put (char c) { return *this; }
void width (int i) { entry->Stream.width(i); }
void fill (char c) { entry->Stream.fill(c); }
void setf (unsigned long val, unsigned long mask) {
entry->Stream.setf( (ios_base::fmtflags)val,
(ios_base::fmtflags)mask); }
void precision (int i) { entry->Stream.precision(i); }
private:
SimS* entry;
char* prompt;
bool is_echoed; // the prompt was echoed
void attach (SimS* s);
void detach (void);
};
--->-8 --- simstream.c -----------------------------------------8-<---
#include <iostream>
#include <fstream>
#include <string>

#include "simstream.h"

using namespace std;

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;
is_opened = 0;
}

SimS::SimS (const char* f)
{
rc = 1;
if (f) {
fp.open(f);
if (fp.bad() || fp.fail()) {
cerr << "Can't open `" << f << "', `cout' will replace it"
<< endl;
Stream = cout;
is_opened = 0;
}
else {
Stream = fp;
is_opened = 1;
}
}
else {
cerr << "Can't open NULL file, `cout' will replace it" << endl;
Stream = cout;
is_opened = 0;
}
}

SimS::~SimS (void)
{
if (is_opened) fp.close();
is_opened = 0;
}

void SimS::flush (void)
{
fp.flush();
}

void SimStream::attach (SimS* s)
{
entry = s;
entry->attached();
}

void SimStream::detach (void)
{
if (entry->detached() == 0) delete entry;
}

SimStream::SimStream (ostream& s, char* p)
{
entry = new SimS(s);
prompt = p ? strdup(p) : p;
is_echoed = 0;
}

SimStream::SimStream (SimStream& s, char* p)
{
this->attach(s.entry);
prompt = p ? strdup(p) : p;
is_echoed = 0;
}

SimStream::SimStream (const char* f, char* p)
{
entry = new SimS(f);
prompt = p ? strdup(p) : p;
is_echoed = 0;
}

SimStream::~SimStream (void)
{
this->detach();
}

bool SimStream::reopen (SimStream& s, char* p)
{
this->detach();
this->attach(s.entry);
prompt = p ? strdup(p) : p;
is_echoed = 0;
if (entry->is_opened) return 1;
else return 0;
}

bool SimStream::reopen (const char* f, char* p)
{
this->detach();
entry = new SimS(f);
prompt = p ? strdup(p) : p;
is_echoed = 0;
if (entry->is_opened) return 1;
else return 0;
}

void SimStream::flush (void)
{
entry->flush();
}

SimStream& SimStream::eek:perator= (SimStream& s)
{
this->detach();
this->attach(s.entry);
return *this;
}

SimStream& SimStream::eek:perator<< (const int i)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << i;
return *this;
}

SimStream& SimStream::eek:perator<< (const unsigned long int i)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << i;
return *this;
}

SimStream& SimStream::eek:perator<< (const unsigned int i)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << i;
return *this;
}

SimStream& SimStream::eek:perator<< (const long int i)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << i;
return *this;
}

SimStream& SimStream::eek:perator<< (const char c)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << c;
if (c == '\n') is_echoed = 0; // reset
return *this;
}

SimStream& SimStream::eek:perator<< (const char* s)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << s;
for (int i = 0; i < strlen(s); i++)
if (s == '\n') is_echoed = 0; // reset
return *this;
}

SimStream& SimStream::eek:perator<< (const float f)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << f;
return *this;
}

SimStream& SimStream::eek:perator<< (const double d)
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << d;
return *this;
}

SimStream& SimStream::eek:perator<< (ostream& o(ostream&))
{
if (prompt)
if (! is_echoed) { entry->Stream << prompt << ' '; is_echoed =
1; }
entry->Stream << o;
is_echoed = 0; // reset
return *this;
}
 
G

Geoffrey S. Knauth

Victor Bazarov said:
You're not supposed to copy streams. If your class keeps a _reference_
to a stream as a member, _initialise_ it, don't assign it.

Thanks. Will try.
 
E

Earl Purple

Geoffrey said:
It's been a while since I programmed in C++, and the language sure has
changed. Usually I can figure out why something no longer compiles, but
this time I'm stumped. A friend has a problem he hoped I could solve,
and I couldn't. Some code he's using, written in 1999, that compiled
fine in 1999, no longer does in 2006 with g++ 4.

This little bit of code:

SimS::SimS (ostream &s)
{
rc = 1;
Stream = s;
is_opened = 0;
}

SimS::SimS (SimS &s)
{
rc = 1;
Stream = s.Stream;
is_opened = 0;
}
< big snip >

The whole thing is flawed - why is he trying to rewrite streams?

If you really want, write your own derivation of ostream. Note that
ostream actually is a template: basic_ostream< char >. Also note that
ostream itself has no virtual members at all apart from its destructor,
and that ostream takes a streambuf* pointer in its constructor, so what
you actually do is write your own derivation of streambuf (actually
basic_streambuf<char> ) and pass that as a pointer to the constructor
of ostream.

If what you want is a wrapper for an ostream that is copyable then that
is basic using boost::shared_ptr (or std::tr1::shared_ptr), i.e.

class ostream_wrapper
{
private:
boost::shared_ptr< ostream > itsStream;

public:
operator ostream&() ( return *itsStream; }
};

plus constructors to get the ostream in there in the first place.
 

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

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top