Calling member functions in base template class

Share the Article

When base is not template class, then the public member functions are inherited and compiler calls in base class functions from derived class.

Simple example with non-template class

The MFDerived::test( ) calls a function “funda( )” which is located in MFBase class.

#include <iostream> //main header using namespace std; //namespace class MFBase { public: void funda() { cout << "MFBase::funda() << endl; } }; class MFDerived : public MFBase { public: void test() { funda(); // calls function in MFBase } }; int main() { MFDerived d; d.test(); return 0; }

Same Example with Template Class

When the base class is template, then compiler cannot simply call base class members in derived class, this is because, now the base is not one class but a family of classes. The compiler can not know how the base class template will be instantiated and whether a specific member function of base will be available in specific instantiation.

#include <iostream> //main header using namespace std; //namespace template<typename T> class MFBase { T x; public: void funda() { cout << "Base<T>::funda( )" << endl; } }; template<typename T> class MFDerived : public MFBase<T> { public: void test() { funda(); // ERROR } }; int main() { MFDerived<int> d; //This line will Error out d.test(); return 0; }
compiler error because the derived class directly calls function in base class which is template

Specific reason for restriction

The C++ compiler cannot generate code to access members directly from base class. Probably, in some instantiation of base class some specific member may not be present or it deleted.

In the following code, the function “funda( )” is deleted in “int” instantiation, i.e., inside MFBase<int>. Therefore, there is no meaning in calling this function from MFDerived<int>. However, for other possible instantiations, the function “funda( )” still exists and they can call this base class function.

#include <iostream> //main header using namespace std; //namespace template<typename T> class MFBase { T x; public: void funda() { cout << "Base<T>::funda( )" << endl; } }; template<> class MFBase<int> { int x; public: void funda() = delete; }; template<typename T> class MFDerived : public MFBase<T> { public: void test() { funda(); // ERROR } }; int main() { MFDerived<int> d; //This line will Error out d.test(); return 0; }

Call to MFDerived::test () will result in an error that funda( ) is not available in the Derived class in MFBase<int> specialization.

There are 3 ways to enable compiler to call printval ( ).

this pointer: Use of this pointer to enable compiler understand that the member is coming from base class

template<typename T> void MFDerived<T>::test() { this->funda(); // this pointer }

Using Directive: Employing a using declaration to bring hidden base class names into a derived class’s scope

class MFDerived : public MFBase<T> { using MFBase<T>::funda; void test() { funda(); // funda from base is available } };

Scope resolution operator: Providing an explicit Base class qualification using scope resolution operator.

template<typename T> void MFDerived<T>::test() { MFBase<T>::funda(); //from MFBase<T> scope }

Main Funda: Template is not one class but a family of classes which can differ from each other in behavior

Related Topics:

What are dependent scope type in templates?
What is an implicit interface? 
Calling member functions in template base class
What is template meta programming (TMP)
How delete keyword can be used to filter polymorphism
Concept of Inline Functions
What is reference collapsing?
How std::forward( ) works?
How std::move() function works?
Smart Pointers: shared_ptr <T> 
Smart Pointers: unique_ptr<T>
What is move constructor ?
Understanding Constant Variables

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *