In my last post, “Class Templates“, I presented the basics. Today, I may surprise you with the inheritance of class templates and the instantiation of member functions of class templates.
Here is the first surprise. At least, it was it for me.
Inherited Member Functions of Class Templates are not Available
Let’s start simple.
I implemented a class Base and Derived.
Derived is public derived from Base and can, therefore, be used in its method callBase (line 2), the member function func from class Base. Okay, I have nothing to add to the output of the program.
Making Base a class template changes the behavior.
I assume the compiler error may surprise you.
The line “there are no arguments to ‘func’ that depend on a template parameter, so a declaration of ‘func’ must be available” from the error message gives the first hint. func is a so-called non-dependent name because its name does not depend on the template parameter
T. Non-dependent names are looked up and bound at the point of the template definition. Consequently, the compiler does not look in the from T dependent base class Base<T>, and there is no name func available outside the class template. Only dependent names are looked up and bound at the point of template instantiation.
This process is called Two Phase Lookup. The first phase is, in particular, responsible for looking up non-dependent names; the second phase is responsible for looking up dependent names.
There are three workarounds to extend the name lookup to the dependent base class. The following example uses all three.
- Make the name dependent: The call this->func1 in line 1 is dependent because this is implicit dependent. The name lookup will consider, in this case, all base classes.
- Introduce the name into the current scope: The expression using Base<T>::func2 (line 2) introduces func2 into the current scope.
- Call the name fully qualified: Calling func3 fully qualified (line 3) will break a virtual dispatch and may cause new surprises.
Which option should you use? In general, I prefer the first option making
this->func1. This solution does even work when you rename your base class.
In the end, here is the output of the program.
Instantiation of Member Functions is Lazy
Lazy means the instantiation of a member function of a class template happens only when needed. Proof? Here we are.
Although the method func2 () (1) of class Lazy is only declared but not defined, the compiler accepts the program. Because func2, a definition of the member function is not necessary.
This laziness of the instantiation process of member functions has two interesting properties.
When you instantiate, for example, a class template
Array2 for various types, only the used member functions are instantiated. This laziness does not hold for a non-template class
Array1. Let me show you an example on C++ Insights.
The member function
getSize() of the class template
Array2 is only instantiated for
myArr2 (1). The call causes this instantiation
C++ Insights shows the truth. The crucial lines in the following screenshot are lines 40 and 59.
Partial Usage of Class Templates
You can instantiate class templates with template arguments that do not support all member functions. When you don’t call those member functions, all is fine.
The class template
Matrix (1) is intentionally simple. It has a type parameter
T, that holds its data in a
std::vector, and can be initialized by a
Matrix supports the member function
printAll() to display all its members. (3) and (4) show its usage. The output operator is not overloaded for
Matrix Consequently, I can create
myMatrix3 having other Matrix objects as members, but I cannot display them.
Enabling line 5 causes a pretty verbose error message of about 274 lines.
I will write about alias templates and template parameters in my next post.
I did a bad marketing job. A few people asked me in the last few days if my C++20 book, published on LeanPub, is available in physical form. Sure, since one month. Choose your preferred Amazon Marketplace.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, and Bhavith C Achar.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,