members in class template not inherited?

Discussion in 'C++' started by not.a@dummy.net, May 19, 2004.

  1. Guest

    When I compile the following code:

    //===================================================
    template <typename T>
    class Foo {
    public:
    T x,y,z;
    };

    template <typename T>
    class Bar : public Foo<T> {
    public:
    Bar<T>& operator+=(const Bar<T>& rhs) {
    x += rhs.x;
    y += rhs.y;
    z += rhs.z;

    return *this;
    }
    };
    //===================================================

    I get the following message from gcc 3.4:

    bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
    bad.cpp:11: error: `x' undeclared (first use this function)
    bad.cpp:11: error: (Each undeclared identifier is reported only once for
    each function it appears in.)
    bad.cpp:12: error: `y' undeclared (first use this function)
    bad.cpp:13: error: `z' undeclared (first use this function)

    If I "un-templatize" the classes Foo and Bar, the code compiles fine. Is
    this a bug in gcc, or am I forgetting something about the way C++ handles
    inheritance and templates?

    Thanks,

    Brett
    , May 19, 2004
    #1
    1. Advertising

  2. wrote in news:eek: in
    comp.lang.c++:

    > When I compile the following code:
    >
    > //===================================================
    > template <typename T>
    > class Foo {
    > public:
    > T x,y,z;
    > };
    >
    > template <typename T>
    > class Bar : public Foo<T> {
    > public:
    > Bar<T>& operator+=(const Bar<T>& rhs) {
    > x += rhs.x;
    > y += rhs.y;
    > z += rhs.z;
    >
    > return *this;
    > }
    > };
    > //===================================================
    >
    > I get the following message from gcc 3.4:
    >
    > bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const
    > Bar<T>&)': bad.cpp:11: error: `x' undeclared (first use this function)
    > bad.cpp:11: error: (Each undeclared identifier is reported only once
    > for each function it appears in.)
    > bad.cpp:12: error: `y' undeclared (first use this function)
    > bad.cpp:13: error: `z' undeclared (first use this function)
    >
    > If I "un-templatize" the classes Foo and Bar, the code compiles fine.
    > Is this a bug in gcc, or am I forgetting something about the way C++
    > handles inheritance and templates?
    >


    It is not inheritance and templates, it si names that *depend* on a
    template paramiter, because of specialization, whatever Foo< T > is
    *depends* on T, so the compiler can't assume that Foo< T > is the
    un-specialized version its already seen, so it can't assume x, y
    and z are members of Foo< T >.

    Ehat to do:

    1) use this->x etc.

    2) use explicit qualification:

    Foo<T>::x += rhs.x;

    Note that rhs.Foo<T>::x isn't required as its effectively (1).

    3) use a using statement:

    template <typename T>
    class Bar : public Foo<T> {
    public:

    using Foo< T >::x;
    using Foo< T >::y;
    using Foo< T >::z;


    Bar<T>& operator+=(const Bar<T>& rhs) {
    x += rhs.x;
    y += rhs.y;
    z += rhs.z;

    return *this;
    }
    };

    HTH.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, May 19, 2004
    #2
    1. Advertising

  3. wrote:
    > When I compile the following code:
    >
    > //===================================================
    > template <typename T>
    > class Foo {
    > public:
    > T x,y,z;
    > };
    >
    > template <typename T>
    > class Bar : public Foo<T> {
    > public:
    > Bar<T>& operator+=(const Bar<T>& rhs) {
    > x += rhs.x;
    > y += rhs.y;
    > z += rhs.z;
    >
    > return *this;
    > }
    > };
    > //===================================================
    >
    > I get the following message from gcc 3.4:
    >
    > bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
    > bad.cpp:11: error: `x' undeclared (first use this function)
    > bad.cpp:11: error: (Each undeclared identifier is reported only once
    > for each function it appears in.)
    > bad.cpp:12: error: `y' undeclared (first use this function)
    > bad.cpp:13: error: `z' undeclared (first use this function)
    >
    > If I "un-templatize" the classes Foo and Bar, the code compiles fine.
    > Is this a bug in gcc, or am I forgetting something about the way C++
    > handles inheritance and templates?


    I think the problem is in name lookup rules. I am too lazy and too busy
    to search through the Standard at this point, but try this fix:

    Bar<T>& operator+=(const Bar<T>& rhs) {
    this->x += rhs.x;
    this->y += rhs.y;
    this->z += rhs.z;

    return *this;
    }

    Victor
    Victor Bazarov, May 19, 2004
    #3
  4. <> wrote in message
    news:eek:...
    > When I compile the following code:
    >
    > //===================================================
    > template <typename T>
    > class Foo {
    > public:
    > T x,y,z;
    > };
    >
    > template <typename T>
    > class Bar : public Foo<T> {
    > public:
    > Bar<T>& operator+=(const Bar<T>& rhs) {
    > x += rhs.x;
    > y += rhs.y;
    > z += rhs.z;
    >
    > return *this;
    > }
    > };
    > //===================================================
    >
    > I get the following message from gcc 3.4:
    >
    > bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
    > bad.cpp:11: error: `x' undeclared (first use this function)
    > bad.cpp:11: error: (Each undeclared identifier is reported only once for
    > each function it appears in.)
    > bad.cpp:12: error: `y' undeclared (first use this function)
    > bad.cpp:13: error: `z' undeclared (first use this function)
    >
    > If I "un-templatize" the classes Foo and Bar, the code compiles fine. Is
    > this a bug in gcc, or am I forgetting something about the way C++ handles
    > inheritance and templates?
    >


    The latter. This is known as dependent name lookup.

    From the standard 'In the definition of a class template ..., if the base
    class of the class template depends upon a template parameter, the base
    clsas scope is not examined during unqualified name lookup'. (section 14.6.2
    para 3)

    Why? I'm not sure. I'm sure there is a good reason.

    The solution is to turn your unqualifed names into qualified names by
    putting this-> in front of them.

    this->x += rhs.x;

    john
    John Harrison, May 19, 2004
    #4
  5. Siemel Naran Guest

    "John Harrison" <> wrote in message
    > news:eek:...


    > > template <typename T>
    > > class Bar : public Foo<T> {
    > > public:
    > > Bar<T>& operator+=(const Bar<T>& rhs) {
    > > x += rhs.x;
    > > y += rhs.y;
    > > z += rhs.z;
    > >
    > > return *this;
    > > }
    > > };


    > From the standard 'In the definition of a class template ..., if the base
    > class of the class template depends upon a template parameter, the base
    > clsas scope is not examined during unqualified name lookup'. (section 14.6.2
    > para 3)
    >
    > Why? I'm not sure. I'm sure there is a good reason.


    The reason I was given is that Foo<T> may be specialized so that it
    does not have members 'x', 'y', and/or 'z'. It does not seem very
    convicing to me, because the errors could spew forth when we finally
    instantiate a faulty Bar<T> such as Bar<int>. Or maybe I'm missing
    something.

    > The solution is to turn your unqualifed names into qualified names by
    > putting this-> in front of them.
    >
    > this->x += rhs.x;


    One can also say

    Foo<T>::x += rhs.x;

    For functions this could be dangerous as it turns off the virtual
    function mechanism (ie. functions will be resolved statically). But I
    prefer the "this->" way of doing it.
    Siemel Naran, May 20, 2004
    #5
    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. christopher diggins
    Replies:
    16
    Views:
    749
    Pete Becker
    May 4, 2005
  2. lovecreatesbeauty
    Replies:
    43
    Views:
    1,299
    Keith Thompson
    Feb 6, 2006
  3. lovecreatesbeauty
    Replies:
    2
    Views:
    578
  4. Replies:
    1
    Views:
    313
  5. 7stud --
    Replies:
    11
    Views:
    398
    7stud --
    Nov 9, 2007
Loading...

Share This Page