1

I am trying to inherit a partially specialised template class from another partially specialised template class. I really appreciate if any one can explain what is the problem.

Example:

template<typename T, typename U>
class Base
{
public:
    int i;
    Base(int _i) : i{_i}
    {}
};

template<typename T, typename U>
class Derived: public Base<T, U>
{
public:
    Derived(int _i) :Base<T, U>{_i}
    {}
};

template<typename U>
class Base<int, U>
{
public:
    int i ;
    Base<int, U>(int _i)
    :i{_i}
    {}
};


template<typename U>
class Derived<int, U>: public Base<int, U>
{
public:
    Derived(int _i)
    : Base<int, U>{_i}
    {}
    void print_i()
    {
        std::cout << i << std::endl;
    }

};

int main()
{
    Derived<int, bool> X(10);
    X.print_i();

    return 0;
}

Expectation: I expected that I can access the Base class member variable from a Derived class member function of the same type.

Current Output: Compile time error says: use of undeclared identifier 'i'

Zingo
  • 600
  • 6
  • 23
  • 2
    In that case, you have to explicitly tell the compiler that `i` should be found in its base, either with a `using` declaration or by prefixing it with `Base::` [edit: or find another way to make it a dependent name]. Here, [related](https://stackoverflow.com/questions/1567730/inheritance-and-templates-in-c-why-are-methods-invisible?noredirect=1&lq=1). – Caninonos Mar 05 '18 at 11:21

1 Answers1

2

This happens because the compiler doesn't look for names in dependent base classes (like templates, that depend upon the type they are instantiated with).

What can you do to solve it?

  1. Use this->i insted of just i

  2. Access i using Base<int, U>::i

  3. Insert using Base<int, U>::member_name before accessing the member (it didn't work for data members for me on coliru)

You can find additional information here.

amc176
  • 1,514
  • 8
  • 19
  • thanks @amc178, Can I assume that there is no impact on performance by using this->i ? what I think it should be no difference from the normal situation where we can access base class members. – Zingo Mar 06 '18 at 01:30
  • 1
    @Zingo When accessing data members the generated assembler is the same, so I would say there is no performance penalty. For virtual member functions, that may not be the case. [Live example](https://godbolt.org/g/dVjUag) – amc176 Mar 06 '18 at 08:15