Skip to main content

Section 23.7 Templated Member Functions

When we define a member function for a templated class, we need to include the template parameters when we write the member functions definitions. For example, if we rewrite our templated Pair<T> to be a class instead of a struct, and we want to define a member function getFirst that returns the first element of the pair, we would do it like this:
Listing 23.7.1.
template<typename T>
class Pair {
  ...
  T getFirst() const;
  ...
};

template<typename T>
T Pair<T>::getFirst() const {
    return first;
}
The definition of getFirst must be preceded by the template parameter list (line 8). And the full formal name of the function must include the class name and the template parameter, so it is is Pair<T>::getFirst. Given a mystery type T, this is the getFirst function for a Pair of type T.
Technically, any mention of Pair should be Pair<T>:
// Constructor definition for making a Pair<T> from two T values
template<typename T>
Pair<T>::Pair<T>(T a, T b) {...}

// Definition of equality operator for Pair<T>
template<typename T>
bool Pair<T>::operator==(const Pair<T>& other) const {...}
However, once we have established that we are writing code for a Pair<T>, the compiler will assume that any use of just Pair really means Pair<T>. Which means we could simplify our code by omitting the template parameter in certain contexts:
template<typename T>
Pair<T>::Pair(T a, T b) {...}  // Note: no <T> after constructor name

// Definition of equality operator for Pair<T>
template<typename T>
bool Pair<T>::operator==(const Pair& other) const {...} // Note: no <T> in parameter type
We still need to start the name of each member function with Pair<T>. That is what tells the compiler that this definition is for a Pair of type T. But once that context is set, we do not need to repeat the template parameter for other uses of Pair.
Here is the complete version of a templated Pair class with member functions:
Listing 23.7.2.
template<typename T>
class Pair {
private:
    T first;
    T second;
public:
    // Full formal declaration
    // Pair<T>(T a, T b);
    // Short form, <T> is implied from class
    Pair(T a, T b);

    // Full formal declaration
    // bool operator==(const Pair<T>& other) const;
    // Short form, <T> is implied from class
    bool operator==(const Pair& other) const;

    T getFirst() const;
    T getSecond() const;
};


template<typename T>
Pair<T>::Pair(T a, T b) {
    first = a;
    second = b;
}

template<typename T>
bool Pair<T>::operator==(const Pair& other) const {
    return (first == other.first) && (second == other.second);
}

template<typename T>
T Pair<T>::getFirst() const {
    return first;
}

template<typename T>
T Pair<T>::getSecond() const {
    return second;
}
You have attempted of activities on this page.