This post will cover some less common syntax that is useful when dealing with templates. The class used to demonstrate the syntax is only as an example, it is not supposed to be a good example of a working smart pointer class.
Let’s start with a simple SmartPointer class and how to write template function definitions outside of the class definition:
As you can see this is pretty similar to defining a normal member function definition outside a class. The only extra things you need are the list of template parameters
template<typename PointerType> before the member function and then the class template parameters between the class name and the scope resolution operator
So pretty simple so far, now let’s try adding a templated member function to our templated class. Member functions that have already been defined previously will be left out of later examples.
So we have overloaded the equality operator to take a
SmartPointer type with a different template type
OtherPointerType. This lets you compare two
SmartPointers without the pointers sharing a type. As you can see defining the template function outside of the class requires the additional declaration of the list of function template parameters
template<typename OtherPointerType> after the list of class template parameters
template<typename PointerType> on line 18. The template argument also requires the template parameter
<OtherPointerType> to indicate it is of a different type to the class.
Next up we’ll try adding a global operator overload that is also a friend of the class. This function will let us compare the
SmartPointer to a raw pointer value without having to worry about which side of the operator the class is on.
This example is not any trickier than before but it does require some forward declaration which the others did not. The need for the forward declarations stems from the fact that the global
operator == overload function must be a friend of the
SmartPointer class so it can access the private member
For the friend declaration function to compile without complaint the global
operator == function must be declared before the class is defined.
For the global
operator == function declaration to compile without complaint the
SmartPointer class must be defined.
So for everything to work we must forward declare the
SmartPointer, then the global
operator == function and then we can define the class with the additional friend function declaration.
Another thing to note is the scope resolution
:: within the friend function declaration, this lets the class know that the function belongs to the global scope, especially useful if the class belongs to a namespace.
As a final step let’s see what the last snippet would look like with the
SmartPointer class belonging to a
There’s not really much change from the last example just the addition of the namespace and scope resolution
lib:: to the global
operator == function
SmartPointer argument and the
namespace lib scope around the class and around the member function definition. Also worth noting that there is no need to close and reopen the namespace between the class definition and member function definition but if they were in separate files (.h header and .inl inline) it might be useful.
Hopefully, if you didn’t already you now know some of the less common syntax used when dealing with templates.