Templates and inheritance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jim West

    #1

    Templates and inheritance

    Can someone please explain to me why the following compiles:

    class A {
    public:
    int d;
    };

    class B : public A {
    public:
    int e;
    void f() { d = e; };
    };



    but if I make A and B templates it gives an error:

    template <typename T>
    class A {
    public:
    T d;
    };

    template <typename T>
    class B : public A<T{
    public:
    int e;
    void f() { d = e; }; // error: identifier "d" is undefined
    };


    This occurs with GNU G++ and Intel ICC. Obviously I am missing a subtlety
    of templates and/or inheritance. (I figured out that changing the line in
    question to

    void f() { A<T>::d = e; };

    corrects the error, but I want understand why it is an error in the first
    place.)
  • Salt_Peter

    #2
    Re: Templates and inheritance

    On Nov 8, 1:06 pm, Jim West <eggplantpa...@ yahoo.comwrote:
    Can someone please explain to me why the following compiles:
    >
    class A {
    public:
    int d;
    >
    };
    >
    class B : public A {
    public:
    int e;
    void f() { d = e; };
    >
    };
    >
    but if I make A and B templates it gives an error:
    >
    template <typename T>
    class A {
    public:
    T d;
    >
    };
    >
    template <typename T>
    class B : public A<T{
    public:
    int e;
    void f() { d = e; }; // error: identifier "d" is undefined
    >
    };
    >
    This occurs with GNU G++ and Intel ICC. Obviously I am missing a subtlety
    of templates and/or inheritance. (I figured out that changing the line in
    question to
    >
    void f() { A<T>::d = e; };
    >
    corrects the error, but I want understand why it is an error in the first
    place.)
    During two-phase name lookup, base classes depending on a template
    argument are not considered. Recall that a member function has a
    hidden this parameter.
    So replace B::f() with a free function instead:

    template< typename T >
    void f( B<T>& r_b )
    {
    r_b.d = r_b.e;
    }

    Comment

    • Hendrik Schober

      #3
      Re: Templates and inheritance

      Jim West wrote:
      Can someone please explain to me why the following compiles:
      >
      class A {
      public:
      int d;
      };
      >
      class B : public A {
      public:
      int e;
      void f() { d = e; };
      };
      >
      >
      >
      but if I make A and B templates it gives an error:
      >
      template <typename T>
      class A {
      public:
      T d;
      };
      >
      template <typename T>
      class B : public A<T{
      public:
      int e;
      void f() { d = e; }; // error: identifier "d" is undefined
      };
      When the compiler encounters 'B' for the first time, it hasn't
      been instantiated, so it doesn't know what 'A' looks like.
      (Remember that 'A' could be specialized for some specific 'T'
      up to the point where 'B' is instantiated for the first time.)
      If it doesn't know 'A', it doesn't know 'A<T>::d'. If you spell
      'A<A>::d' out explicitly, it becomes a so called dependent type
      (which means it depends on some template parameter which isn't
      known when the template is parsed for the first time) and its
      lookup is deferred until 'B' is actually instantiated.
      This occurs with GNU G++ and Intel ICC. Obviously I am missing a subtlety
      of templates and/or inheritance. (I figured out that changing the line in
      question to
      >
      void f() { A<T>::d = e; };
      >
      corrects the error, but I want understand why it is an error in the first
      place.)
      HTH,

      Schobi

      Comment

      Working...