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

Discussion in 'C++' started by Geoffrey S. Knauth, Jan 17, 2006.

  1. 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<char> >& std::basic_ios<char, std::char_traits<char>
    >::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);
    };
     
    Geoffrey S. Knauth, Jan 17, 2006
    #1
    1. Advertising

  2. Re: error: 'std::ios_base& std::ios_base::eek:perator=(const std::ios_base&)'is private

    Geoffrey S. Knauth wrote:
    > 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
     
    Victor Bazarov, Jan 17, 2006
    #2
    1. Advertising

  3. Re: error: 'std::ios_base& std::ios_base::eek:perator=(const std::ios_base&)'is private

    Geoffrey S. Knauth wrote:
    > 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.
     
    Jacek Dziedzic, Jan 17, 2006
    #3
  4. On Tue, 17 Jan 2006 14:31:07 -0500, (Geoffrey S.
    Knauth) wrote:

    >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
    > 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
    >};


    --
    Bob Hairgrove
     
    Bob Hairgrove, Jan 17, 2006
    #4
  5. Re: error: 'std::ios_base& std::ios_base::eek:perator=(const std::ios_base&)' is private

    Jacek Dziedzic <jacek@no_spam.tygrys.no_spam.net> wrote:
    > 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;
    }
     
    Geoffrey S. Knauth, Jan 18, 2006
    #5
  6. Victor Bazarov <> wrote:
    > > 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.


    Thanks. Will try.

    --
    Geoffrey S. Knauth | http://knauth.org/gsk
     
    Geoffrey S. Knauth, Jan 18, 2006
    #6
  7. Geoffrey S. Knauth

    Earl Purple Guest

    Geoffrey S. Knauth wrote:
    > 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.
     
    Earl Purple, Jan 18, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tim Clacy
    Replies:
    15
    Views:
    2,713
    Kanenas
    May 30, 2005
  2. DaVinci
    Replies:
    3
    Views:
    430
    Jacek Dziedzic
    Apr 9, 2006
  3. DaVinci
    Replies:
    7
    Views:
    726
    Fraser Ross
    Apr 7, 2006
  4. Robin
    Replies:
    9
    Views:
    1,265
  5. Javier
    Replies:
    2
    Views:
    585
    James Kanze
    Sep 4, 2007
Loading...

Share This Page