Jeffrey
Jeffrey

Reputation: 4506

Why the same type duplicated declared in the gcc library

In the gcc library, the template basic_stringbuf is derived from basic_streambuf. In the base class basic_streambuf, the type names, such as char_type, traits_type, are already declared. Why they are duplicated declared in the child class basic_stringbuf?

The related code is pasted below.

// c++/4.2.1/streambuf
template<typename _CharT, typename _Traits>
    class basic_streambuf 
    {
    public:
      //@{
      /**
       *  These are standard types.  They permit a standardized way of
       *  referring to names of (or names dependant on) the template
       *  parameters, which are specific to the implementation.
      */
      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;
      //@}

      //@{
      /**
       *  @if maint
       *  This is a non-standard type.
       *  @endif
      */
      typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
      //@}
…
};

// c++/4.2.1/sstream
template<typename _CharT, typename _Traits, typename _Alloc>
    class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
    {
    public:
      // Types:
      typedef _CharT                    char_type;
      typedef _Traits                   traits_type;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 251. basic_stringbuf missing allocator_type
      typedef _Alloc                        allocator_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 basic_streambuf<char_type, traits_type>   __streambuf_type;
      typedef basic_string<char_type, _Traits, _Alloc>  __string_type;
      typedef typename __string_type::size_type     __size_type;
…
};

Update:

The char_type is already declared in the parent class as a public member. The child class can use it directly. My question is why not gcc implements the basic_stringbuf as below

template<typename _CharT, typename _Traits, typename _Alloc>
    class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
    {
    public:
      // Types:
      //typedef _CharT                  char_type;
      //typedef _Traits                     traits_type;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 251. basic_stringbuf missing allocator_type
      typedef _Alloc                        allocator_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 basic_streambuf<char_type, traits_type>   __streambuf_type;
      typedef basic_string<char_type, _Traits, _Alloc>  __string_type;
      typedef typename __string_type::size_type     __size_type;
…
};

EDIT:

Thanks K-ballo. I think your answer makes sense. I tried the code below. The type name char_type can't be used in the child class.

template<typename _CharT>
class Base
{
public:
    typedef _CharT char_type; 
};

template<typename _CharT>
class Child : public Base<_CharT>
{
private:
    char_type _M_Data; // FAIL: Unknown type name 'char_type'
};

Upvotes: 4

Views: 276

Answers (1)

K-ballo
K-ballo

Reputation: 81349

Have you tried doing that? The base class basic_streambuf<_CharT, _Traits> is a dependent type, the compiler won't know what specialization of basic_streambuf (if any) will this base be until the actual type is instantiated. Because of that, definitions for the base class are not visible in the derived class. To make a type declared in a dependent base class visible one usually does typedef typename base_class::some_type some_type;, gcc just decided to redefine them again just as the base does.

It reduces to the fact that char_type, though declared in the parent class as a public member, cannot be used directly by the child class. It would have to use it as

 typename basic_streambuf< _CharT, _Traits >::char_type

Upvotes: 2

Related Questions