the typename keyword - inheriting types from templated classes

Discussion in 'C++' started by Chris Foster, Aug 23, 2004.

  1. Chris Foster

    Chris Foster Guest

    Hi, I'm having some difficulty using types which are defined in a base
    class inside a derived class. The problem crops up using template
    classes.

    The following test code encapsulates what I'd like to do, but doesn't
    compile with g++ (v3.3.3).

    //---------------------------------------------------------
    // A = base class
    template <typename T>
    class A
    {
    public:
    enum Aenum {foo, bar};
    };

    // B = class derived from A; inherits type A<T>::Aenum.
    template <typename T>
    class B : public A<T>
    {
    public:
    Aenum ae;
    B(Aenum ae)
    {
    this->ae = ae;
    }
    };
    //---------------------------------------------------------

    When I try to compile, g++ complains with the errors

    templtest.cpp:19: warning: `B<T>::Aenum' is implicitly a typename
    templtest.cpp:19: warning: implicit typename is deprecated, please see
    the documentation for details
    templtest.cpp:21: warning: `B<T>::Aenum' is implicitly a typename
    templtest.cpp:21: warning: implicit typename is deprecated, please see
    the documentation for details

    If instead I explicitly tell the compiler that Aenum is a type,
    defining the class B by:

    //---------------------------------------------------------
    template <typename T>
    class B : public A<T>
    {
    public:
    typename A<T>::Aenum ae;
    B(typename A<T>::Aenum ae = foo)
    {
    this->ae = ae;
    }
    };
    //---------------------------------------------------------

    then the compilation goes without a problem. However, it seems as
    though the compiler has all the information it could need to determine
    that Aenum is a type from the original definition. Certinally if we
    define Aenum within the derived class B rather than the base class A
    then there's no problem.

    So my question is: is this the behaviour that we *should* expect from
    g++, and if so, why?
     
    Chris Foster, Aug 23, 2004
    #1
    1. Advertising

  2. Short: GCC is right.
    Longer: You can have e.g. A<int> specialization with Aenum not being type
    but something else. There is nice example in C++ Templates - The Complete
    Guide:

    template<typename T>
    class Trap {
    public:
    enum {x}; // (1) x is not a type here
    };

    template<typename T>
    class Victim
    {
    public:
    int y;
    void poof () {
    Trap<T>::x * y; // (2) declaration or multiplication?
    }
    };

    template<>
    class Trap<void> { // evil specialization
    public:
    typedef int x; // (3) x is type here
    };

    void boom (Victim<void> & boom)
    {
    bomb.poof ();
    }

    As you can see for Trap<void>::x is type and (2) would mean declaration of
    varibable y. But for the generic case it would be multiplication, so to
    resolve this ambiguity the compiler assumes variable unless typename is
    specified in that case it knows it is a type.

    V.H.



    "Chris Foster" <> wrote in message
    news:...
    > Hi, I'm having some difficulty using types which are defined in a base
    > class inside a derived class. The problem crops up using template
    > classes.
    >
    > The following test code encapsulates what I'd like to do, but doesn't
    > compile with g++ (v3.3.3).
    >
    > //---------------------------------------------------------
    > // A = base class
    > template <typename T>
    > class A
    > {
    > public:
    > enum Aenum {foo, bar};
    > };
    >
    > // B = class derived from A; inherits type A<T>::Aenum.
    > template <typename T>
    > class B : public A<T>
    > {
    > public:
    > Aenum ae;
    > B(Aenum ae)
    > {
    > this->ae = ae;
    > }
    > };
    > //---------------------------------------------------------
    >
    > When I try to compile, g++ complains with the errors
    >
    > templtest.cpp:19: warning: `B<T>::Aenum' is implicitly a typename
    > templtest.cpp:19: warning: implicit typename is deprecated, please see
    > the documentation for details
    > templtest.cpp:21: warning: `B<T>::Aenum' is implicitly a typename
    > templtest.cpp:21: warning: implicit typename is deprecated, please see
    > the documentation for details
    >
    > If instead I explicitly tell the compiler that Aenum is a type,
    > defining the class B by:
    >
    > //---------------------------------------------------------
    > template <typename T>
    > class B : public A<T>
    > {
    > public:
    > typename A<T>::Aenum ae;
    > B(typename A<T>::Aenum ae = foo)
    > {
    > this->ae = ae;
    > }
    > };
    > //---------------------------------------------------------
    >
    > then the compilation goes without a problem. However, it seems as
    > though the compiler has all the information it could need to determine
    > that Aenum is a type from the original definition. Certinally if we
    > define Aenum within the derived class B rather than the base class A
    > then there's no problem.
    >
    > So my question is: is this the behaviour that we *should* expect from
    > g++, and if so, why?
     
    Vaclav Haisman, Aug 23, 2004
    #2
    1. Advertising

  3. Chris Foster

    Chris Foster Guest

    > Short: GCC is right.
    > Longer: You can have e.g. A<int> specialization with Aenum not being type
    > but something else. There is nice example in C++ Templates - The Complete
    > Guide:
    >
    > template<typename T>
    > class Trap {
    > public:
    > enum {x}; // (1) x is not a type here
    > };
    >
    > template<typename T>
    > class Victim
    > {
    > public:
    > int y;
    > void poof () {
    > Trap<T>::x * y; // (2) declaration or multiplication?
    > }
    > };
    >
    > template<>
    > class Trap<void> { // evil specialization
    > public:
    > typedef int x; // (3) x is type here
    > };
    >
    > void boom (Victim<void> & boom)
    > {
    > bomb.poof ();
    > }
    >
    > As you can see for Trap<void>::x is type and (2) would mean declaration of
    > varibable y. But for the generic case it would be multiplication, so to
    > resolve this ambiguity the compiler assumes variable unless typename is
    > specified in that case it knows it is a type.


    Aha! Thanks very much, I must confess I'm a little surprised that the
    above doesn't result in a name collision (I just need to know more
    about how specialisation works I guess :-/ )

    It's a pity though, I was hoping I could avoid the notational
    nightmare which using the typename keyword causes...

    CF
     
    Chris Foster, Aug 23, 2004
    #3
    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. RA Scheltema
    Replies:
    3
    Views:
    404
    RA Scheltema
    Jan 6, 2004
  2. Marijn
    Replies:
    5
    Views:
    464
    Marijn
    Feb 13, 2004
  3. Anonymous
    Replies:
    2
    Views:
    1,328
    John Carson
    Apr 13, 2004
  4. Exits Funnel
    Replies:
    1
    Views:
    320
    Sharad Kala
    Jan 8, 2005
  5. Jakob Bieling

    Q: typename or not typename?

    Jakob Bieling, Mar 14, 2006, in forum: C++
    Replies:
    2
    Views:
    356
    Rolf Magnus
    Mar 14, 2006
Loading...

Share This Page