This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

derivation problems with templates


There appear to be some issues when deriving from templates. When I try
to compile the test case below with the latest 3.4 snapshot I get a
number of compile errors like so:

gccStreamTest.C:34: error: ISO C++ forbids declaration of
`char_type_M_unbuf' with no type
gccStreamTest.C: In member function `int my_stdio_filebuf<_CharT,
_Traits>::fd()':
gccStreamTest.C:50: error: `_M_file' undeclared (first use this
function)
gccStreamTest.C:50: error: (Each undeclared identifier is reported only
once for each function it appears in.)
gccStreamTest.C: In constructor `my_stdio_filebuf<_CharT,
_Traits>::my_stdio_filebuf(int, std::_Ios_Openmode, size_t)':
gccStreamTest.C:62: error: `_M_file' undeclared (first use this
function)
gccStreamTest.C:65: error: `_M_mode' undeclared (first use this
function)
gccStreamTest.C:69: error: `_M_buf' undeclared (first use this function)
gccStreamTest.C:69: error: `_M_unbuf' undeclared (first use this
function)
gccStreamTest.C:70: error: `_M_buf_size' undeclared (first use this
function)
gccStreamTest.C:71: error: `_M_buf_size_opt' undeclared (first use this
function)

The complaint about char_type is wrong since char_type is typdefed to
_CharT which is a template argument.

The complaint about _M_file not being defined is also incorrect since
_M_file is a member of the base class.

Please let me know if I should file a bug on this issue.

Thanks,
Robert

file: gccStreamTest.C

#include <stdio.h>
#include <fcntl.h>
#include <fstream>

using std::ios_base;
using std::char_traits;


template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
class my_stdio_filebuf : public std::basic_filebuf<_CharT, _Traits>
{
public:
    // Types:
    typedef _CharT                     	        char_type;
    typedef _Traits                    	        traits_type;
    typedef typename traits_type::int_type 	int_type;
    typedef typename traits_type::pos_type 	pos_type;
    typedef typename traits_type::off_type 	off_type;
    typedef std::size_t                         size_t;
      
protected:
    // Stack-based buffer for unbuffered input.
    char_type	_M_unbuf[4];
      
public:
    // default ctor, deferred initialization
    my_stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {}

    // ctor to support creation with file descriptor
    my_stdio_filebuf(int __fd, ios_base::openmode __mode, 
                      size_t __size = static_cast<size_t>(BUFSIZ));

    // ctor to support creation with standard C FILE*
    my_stdio_filebuf(std::__c_file* __f, ios_base::openmode __mode, 
                      size_t __size = static_cast<size_t>(BUFSIZ));

    virtual ~my_stdio_filebuf();

    int fd() { return _M_file.fd(); }
};

template<typename _CharT, typename _Traits>
my_stdio_filebuf<_CharT, _Traits>::~my_stdio_filebuf()
{ 
}

template<typename _CharT, typename _Traits>
my_stdio_filebuf<_CharT, _Traits>::my_stdio_filebuf(
    int __fd, ios_base::openmode __mode,size_t __size)
{
    _M_file.sys_open(__fd, __mode, false);
    if (this->is_open())
    {
        _M_mode = __mode;
        if (__size > 0 && __size < 4)
        {
            // Specify unbuffered.
            _M_buf = _M_unbuf;
            _M_buf_size = __size;
            _M_buf_size_opt = 0;
        }
        else
        {
            _M_buf_size_opt = __size;
            _M_allocate_internal_buffer();
        }
        _M_set_indeterminate();
    }
}

template<typename _CharT, typename _Traits>
my_stdio_filebuf<_CharT, _Traits>::my_stdio_filebuf(
    std::__c_file* __f, std::ios_base::openmode __mode,size_t __size)
{
    _M_file.sys_open(__f, __mode);
    if (this->is_open())
    {
        _M_mode = __mode;
        if (__size > 0 && __size < 4)
        {
            // Specify unbuffered.
            _M_buf = _M_unbuf;
            _M_buf_size = __size;
            _M_buf_size_opt = 0;
        }
        else
        {
            _M_buf_size_opt = __size;
            _M_allocate_internal_buffer();
        }
        _M_set_indeterminate();
    }
};


template<typename _CharT, typename _Traits>
class my_stdio_ifstream : public std::basic_istream<_CharT, _Traits>
{
public:
    // Types:
    typedef _CharT char_type;
    typedef _Traits traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;

    friend class ios_base; // For sync_with_stdio.

    // Default ctor
    explicit
    my_stdio_ifstream() : std::basic_istream<char_type,
traits_type>(NULL), 
                           myBuf() 
        {this->init(&myBuf);}

    // Standard ctor
    explicit
    my_stdio_ifstream(const char* myName, 
                       ios_base::openmode myMode = ios_base::in)
        : std::basic_istream<char_type, traits_type>(NULL), 
          myBuf()
        {
            this->init(&myBuf);
            this->open(myName, myMode);
        }

    // ctor that takes a C FILE*
    explicit
    my_stdio_ifstream(std::__c_file* myFile)
        : std::basic_istream<char_type, traits_type>(NULL),
          myBuf(myFile, ios_base::in, 0)
        {this->init(&myBuf);}

    // ctor that takes a file descriptor
    explicit
    my_stdio_ifstream(int fd)
        : std::basic_istream<char_type, traits_type>(NULL),
          myBuf(fd,ios_base::in, 0) 
        {this->init(&myBuf);}
    

    ~my_stdio_ifstream() {}

    my_stdio_filebuf<char_type>* rdbuf() const
        {return const_cast<my_stdio_filebuf<char_type>*>(&myBuf);}

    int fd() {return myBuf.fd();}

    bool is_open() {return myBuf.is_open();}
    
    void open(const char* name, std::ios_base::openmode opMode =
ios_base::in)
        {
            if (! myBuf.open(name, opMode | ios_base::in))
                this->setstate(ios_base::failbit);
        }

    void close()
        {
            if (! myBuf.close())
                this->setstate(ios_base::failbit);
        }

private:
    my_stdio_filebuf<char_type> myBuf;
};

template<typename _CharT, typename _Traits>
class my_stdio_ofstream : public std::basic_ostream<_CharT, _Traits>
{
public:
    // Types:
    typedef _CharT char_type;
    typedef _Traits traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;

    friend class ios_base; // For sync_with_stdio.

    // Default ctor
    explicit
    my_stdio_ofstream() : std::basic_ostream<char_type,
traits_type>(NULL), 
                           myBuf() 
        {this->init(&myBuf);}

    // Standard ctor
    explicit
    my_stdio_ofstream(const char* myName, 
                       ios_base::openmode myMode = ios_base::out)
        : std::basic_ostream<char_type, traits_type>(NULL), 
          myBuf()
        {
            this->init(&myBuf);
            this->open(myName, myMode);
        }

    // ctor that takes a C FILE*
    explicit
    my_stdio_ofstream(std::__c_file* myFile)
        : std::basic_ostream<char_type, traits_type>(NULL),
          myBuf(myFile,ios_base::out)
        {this->init(&myBuf);}

    // ctor that takes a file descriptor
    explicit
    my_stdio_ofstream(int fd)
        : std::basic_ostream<char_type, traits_type>(NULL),
          myBuf(fd, ios_base::out) 
        {this->init(&myBuf);}
    

    ~my_stdio_ofstream() {}

    my_stdio_filebuf<char_type>* rdbuf() const
        {return const_cast<my_stdio_filebuf<char_type>*>(&myBuf);}

    int fd() {return myBuf.fd();}

    bool is_open() {return myBuf.is_open();}
    
    void open(const char* name, std::ios_base::openmode opMode =
ios_base::out)
        {
            if (! myBuf.open(name, opMode | ios_base::out))
                this->setstate(ios_base::failbit);
        }

    void close()
        {
            if (! myBuf.close())
                this->setstate(ios_base::failbit);
        }

private:
    my_stdio_filebuf<char_type> myBuf;
};

template<typename _CharT, typename _Traits>
class my_stdio_fstream : public std::basic_iostream<_CharT, _Traits>
{
public:
    // Types:
    typedef _CharT char_type;
    typedef _Traits traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;

    friend class ios_base; // For sync_with_stdio.

    // Default ctor
    my_stdio_fstream() : std::basic_iostream<char_type,
traits_type>(NULL), 
                           myBuf() 
        {this->init(&myBuf);}

    // Standard ctor
    my_stdio_fstream(const char* myName, 
                       ios_base::openmode myMode =
ios_base::in|ios_base::out)
        : std::basic_iostream<char_type, traits_type>(NULL),
          myBuf()
        {
            this->init(&myBuf);
            this->open(myName, myMode);
        }

    // ctor that takes a C FILE*
    my_stdio_fstream(std::__c_file* myFile)
        : std::basic_iostream<char_type, traits_type>(NULL),
          myBuf(myFile, ios_base::in|ios_base::out)
        {this->init(&myBuf);}

    // ctor that takes a file descriptor
    my_stdio_fstream(int fd)
        : std::basic_iostream<char_type, traits_type>(NULL),
          myBuf(fd,ios_base::in|ios_base::out) 
        {this->init(&myBuf);}
    

    ~my_stdio_fstream() {}

    my_stdio_filebuf<char_type>* rdbuf() const
        {return const_cast<my_stdio_filebuf<char_type>*>(&myBuf);}


    int fd() {return myBuf.fd();}

    bool is_open() {return myBuf.is_open();}
    
    void open(const char* name, 
              std::ios_base::openmode opMode =
ios_base::in|ios_base::out)
        {
            if (! myBuf.open(name, opMode))
                this->setstate(ios_base::failbit);
        }

    void close()
        {
            if (! myBuf.close())
                this->setstate(ios_base::failbit);
        }

private:
    my_stdio_filebuf<char_type> myBuf;
};


template<typename _CharT, typename _Traits = char_traits<_CharT> >
    class my_stdio_ifstream;
template<typename _CharT, typename _Traits = char_traits<_CharT> >
    class my_stdio_ofstream;
template<typename _CharT, typename _Traits = char_traits<_CharT> >
    class my_stdio_fstream;

template class my_stdio_filebuf<char>; 
// Instantiate the stream templates
template class my_stdio_ifstream<char>;
template class my_stdio_ofstream<char>;
template class my_stdio_fstream<char>;
typedef my_stdio_ifstream<char> my_ifstream;
typedef my_stdio_ofstream<char> my_ofstream;
typedef my_stdio_fstream<char> my_fstream;


int
main()
{
    fprintf(stderr,"Open the file\n");
    int fd = creat("myTest.txt", O_WRONLY);
    fprintf(stderr,"Create the stream\n");
    my_ofstream myStrm(fd);
    fprintf(stderr,"Write to the stream\n");
    myStrm << "Hello world" << std::endl;
    fprintf(stderr,"Close the stream\n");
    myStrm.close();
}



-- 
Robert Schweikert                   MAY THE SOURCE BE WITH YOU
rjschwei@cox.net                               LINUX



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]