This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
derivation problems with templates
- From: Robert Schweikert <rjschwei at cox dot net>
- To: gcc-dev <gcc at gcc dot gnu dot org>
- Cc: rjschwei at cox dot net
- Date: 24 Feb 2004 15:57:59 -0500
- Subject: derivation problems with templates
- Organization:
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