eaglefreeman
eaglefreeman

Reputation: 854

Inheriting from template abstract class

I have this code structure:

class A
{
protected:
    int u;
    int z;

public:
    A(int uu,
      int zz)
    :u(uu),
     z(zz)
    {};

    int get() const
    {
    return u;
    };

    virtual void blah() = 0;
};

template <class T>
class B : public A
{
protected:
    std::vector<T> xxxx;
public:
    B(int uu,
      int zz,
      int bbb)
    :A(uu,
       zz)
    {
    for(size_t i = 0; i < bbb; i ++)
        xxxx[i] = 0;
    };

    virtual void blah()
    {
    u = u + 1;
    };
};

template <class T>
class C : public B<T>
{
protected:
    int qrqr;

public:
    C(int uu,
      int zz,
      int bbb,
      int qrqrqr)
    :B<T>(uu,
          zz,
          bbb),
     qrqr(qrqrqr)
    {
    };

    virtual void blah()
    {
    u = u + qrqr;
    };
};

When I compile I get this error:

 
error: 'u' was not declared in this scope
    at line:  u = u + qrqr;

Though u is clearly an element of C because A is a base of C through B.

I read here: Class template inheritance C++ that the proper way to inherit from class template is either to specialize the class or to have the inherited class to be template and this is what I did here. The compiler doesn't seem to complain about it anyway. Could it be because A is an abstract class?

What did I do wrong?

Thanks!

Upvotes: 2

Views: 522

Answers (1)

Ami Tavory
Ami Tavory

Reputation: 76297

This is a problem with a nondependent name - the member you're referring to does not depend on the template parameter. The compiler does not look in dependent base classes (like B<T>) when looking up nondependent names (like u).

You can solve it by using

this->u = this->u + qrqr;

which specifies to the compiler which u you mean.

(coliru)

There are at least two other ways, by calling B<T>::u, or writing using B<T>::u; in the function before this line.

Read more about it here.

Upvotes: 1

Related Questions