Hello again. I'm sorry to come back with the same topic, but I have another (small) question. This is: What's the proper way to specialize class templates?
I mean, I specialized a class template the following way:
// Everything is on Pair.h
#ifndef PAIR_H
#define PAIR_H
#include <iostream>
#include <string>
// Class template
template <class T>
class Pair
{
private:
// attributes
T objects[2];
public:
// constructor
Pair (T a, T b) {
objects[0] = a;
objects[1] = b;
}
// methods
T product () {
return objects[0] * objects[1];
}
};
// class template specialization
template <>
class Pair <std::string>
{
private:
// attributes
std::string objects[2];
public:
// constructor
Pair (std::string a, std::string b) {
objects[0] = a;
objects[1] = b;
}
// methods
std::string concatenate () {
return objects[0] + objects[1];
}
}
#endif // PAIR_H
I know that templates aren't compiled unless they are specialized templates. That's why they must be defined when declared. In the past thread I made, I was told that when working with function templates, I could declare the specialization in the header and define it in the source file (I didn't know it back then, but now it seems fairly obvious =P). But what happens to class template specializations? How can/should I separate the code?
With classes you don't have this issue - you can just leave it in your header file. Imagine a non-template class definition with functions defined in the header file - it is the same process - the member functions defined in the class body are automatically declared inline and therefore it is allowed to be defined in multiple translation units.
That actually brings me back to your original question about template member function specialization. You could just declare it inline and leave it in the header file:
1 2 3 4 5
// Specialization of template function
template <>
inlinevoid Test::function (char data) {
std::cout << 'Z' << std::endl;
}
Well, it depends on many things. If the functions are really small then it's ok to leave them in the header file. Otherwise, for non-template classes you move the implementation in the source files and for templates - you also move the implementations into a separate file (I usually give them the "inl" extension - inline functions) which is then directly included in the header file.
Same with specializations. If they are different in principle to non-specialized templates, then, you would need to expose these differences to the programmer using your code, and maybe leave it in the main header file for your class (and write plenty of comments, and also think - if it's so different - should it be a specialization rather than a different class?). But if the specialization differ only in implementation details - then move it to another file and include it into the main one - the user shouldn't really care about it and only use the generic interface.