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:
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.
// 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.
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;
}
Checkpoint23.7.1.
Imagine the Pair class had a function copy that took in another Pair of the same type and had a return type of void. (The function would copy the data from the other object into the current one. The other object would not be modified.) What would its prototype look like?