×
Get in touch

Get in touch with Binary

Binary Studio website uses cookies to enhance your browsing experience. By continuing to use our site, you agree to our Privacy Policy and use of cookies.

Learn more more arrow
Agree
andrew.kramarenko@binary-studio.com'
Andrew Kramarenko C++ Developer 14.08.2014

7. Template as double-edged sword: go further with OOP!


Introduction

In the previous article I began to talk about templates. In this topic I'm going to continue with interacting templates in object oriented design and I want to talk about typename keyword. Less introduction words - let's see what I am talking about.

Templates and class features

or level up your project with terrible things

In previous article I declared class SimpleTemplateClass<DataType>. I propose to inherit from this class a new one and add new features of templates. There is a big chuck of code which I will describe below:

First of all look at (1.1) line. There is a new feature of template argument list:

It is called default templates argument. If we don't set this argument then it will be int by default:

In such declaration variable's DataType will be taken as int type by default. You can use such feature only in the trailing template arguments. It means you can't write such code:

It is wrong and will cause compile error. It will compile when you define default argument for B or move template argument A to the end of the list.

In line (1.2) we inherit our new class InheritTemplateClass from SimpleTemplateClass. As you see code set template argument DataType for inherited template class. It is requirement of template inheritance to determine template argument list of parent class.

In line (1.3) we call appropriate constructor of template parent class with determined template argument list.

Lines (1.4) and (1.5) are very interesting. I want to show you such an example code:

In lines (2.1) and (2.2) we have made instances of template classes with different types. Line (2.3) causes compile error because arrayKeeperDouble and arrayKeeperInt are different auto-generated types. If they are generated from one template, it doesn't mean that they are same and compiler doesn't know how to assign them.

Overloaded assignment operator of InheritTemplateClass<DataType> in lines (1.4) and (1.5) helps to deal with this. And yes, it is template method of template cs! It defines new template with new template argument RValueType in line (1.4) which is used as type for template argument in other SimpleTemplateClass<RValueType> instance. In body of such operator= we make new internal array and through static_cast<T>() in line (1.6) assign to new array values from array of assigned right hand side instance. static_cast<T>() provide converting from one type to another which helps a lot in line (2.4).

 

Templates and virtual methods

or it is not always what you expect

 

In the previous section I have told about inheritance which is one of OOP pillars. Let's observe virtual methods which provide polymorphism in C++. There is a pitfall with template methods. Let's see such huge chuck of code:

Let's observe everything in its order:

(3.1) is base class which has virtual method (3.2).

(3.3) is inherited class from base class and it has template method (3.4) with the same name as virtual method of parent class. If you add virtual key word for (3.4) it will causes compile error, because actually it can't overload virtual method even if it has same auto-generated signature. But some programmers can expect overloading because even without virtual key word it must work.

(3.5) is template class which inherited by BaseClassA and it also has method VirtualMethod as parent class.

Let's check how everything works by running such code:

 

Line (4.1) confirms what's stated above: there is no call of overloaded virtual method of child class because it wasn't exactly overloaded. It calls method of the base class.

But line (4.2) shows that for template class which is generated VirtualMethod() with int type it works as expected. It calls overloaded method and even its signature was generated by template.

Otherwise it looks as in line (4.3). There was generated VirtualMethod() with double type which doesn't overload virtual method. So this line calls method from the base class.

As you see there are issues with overloading template classes and methods so beware: it won't work every time even if you hope so.

 

Key word typename

or let compiler know what you said

 

typename is more than you think. Before it was used only in template argument list, but it has another useful meaning. It is necessary when you have some internal class in other class and you want to use that type from template argument type. I am sure it sounds horrible and confuses you. So, let's see it in the next code:

In line (5.1) we have internal class of ExternalClass which is created by method in line (5.2). Declared class in line (5.3) uses InternalClass as type for its field in line (5.4), but we need to get this type through ExternalClass, which is default template type of ClassUsesTypename class. Compiler has lack of information here, because expression TData::InternalClass looks for its like many other things: is it static field or obtaining address of method? It guesses that it is type, but maybe it is programmer typo or mistake so compiler shows error here without required typename keyword in line (5.4).

This is for what typename stands for. If you have experience with iterators from C++ standard library, you probably faced with this keyword before. Now you know why it is required, because iterators are internal classes of containers.

 

Conclusion

 

Today I have discussed interacting templates in object oriented designed solutions. Article shows different issues with inheritance of classes and overloading of virtual methods. Besides this there were extra features of templates such as: template methods, default template argument type. As separated entity was shown typename keyword which is useful to give the cue for compiler when we use internal class of templated type.

For the next article about templates I have left such questions as: specification of templates, duck typing and calculation at compile time. So see you soon.

 

Examples of code from article you can find in my Github repository.

My previous articles from “.CPP files” series are: