What are most important things you know about templates: hidden features, common mistakes, best and most useful practices, tips...common mistakes/oversight/assumptions
I'd have to say Coplien's Curiously Recurring Template Pattern (CRTP) is the one template trick that I find myself reaching for over & over again. Essentially it allows you to inject statically customized functionality into a derived class by inheriting from a base class that is parameterized on the derived class name. Mind boggling, but amazingly useful (some call it static polymorphism).
Also, I'll second Neil Butterworth's advice to read "C++ Templates" and throw in Alexandrescu's Modern C++ Design.
I tend to use templates quite a lot to avoid duplication of code, and to increase safety through compile checks.
In general, it helps to think while typing about what the compiler is going to do, and how the code will be generated for each type.
Being very iterative in development and building the template complexity little by little has helped me avoiding sinking in compile error messages. Don't forget to keep a simple (or mock) instantiation of the template somewhere, otherwise you might have some nasty surprises when you instantiate a monster template for the first time.
Finally, when there is no way out, get to read these compile error messages! They might look quite scary at first, but they really are helpful. Maybe at first extracting the first one, copying it in a text editor and making it look pretty will help getting used to them, and it quickly becomes second nature to read through.
Template Tip of the Day: Did you know you can specialize chosen functions of template instantiations:
#include <iostream>
#include <vector>
namespace std {
template<>
void vector<int>::clear() {
std::cout << "Clearing..." << std::endl;
resize(0);
}
}
int main() {
std::vector<int> v;
v.push_back(1);
v.clear();
}
ouputs: Clearing...
The STL is your friend.
From "Exceptional C++ style", Item 7: function overload resolution happens before templates specialization. Do not mix overloaded function and specializations of template functions, or you are in for a nasty surprise at which function actually gets called.
template<class T> void f(T t) { ... } // (a)
template<class T> void f(T *t) { ... } // (b)
template<> void f<int*>(int *t) { ... } // (c)
...
int *pi; f(pi); // (b) is called, not (c)!
On top of Item 7:
Worse yet, if you omit the type in template specialization, a different function template might get specialized depending on the order of definition and as a result a specialized function may or may not be called.
Case 1:
template<class T> void f(T t) { ... } // (a)
template<class T> void f(T *t) { ... } // (b)
template<> void f(int *t) { ... } // (c) - specializes (b)
...
int *pi; f(pi); // (c) is called
Case 2:
template<class T> void f(T t) { ... } // (a)
template<> void f(int *t) { ... } // (c) - specializes (a)
template<class T> void f(T *t) { ... } // (b)
...
int *pi; f(pi); // (b) is called
I've used c++ and templates a lot, including more advanced template metaprogramming and my feeling is that their usefulness is overrated. They were originally added to the c++ language, well after the creation of c++, to tack on a generic programming capability. This simply allows one to focus on the logic of the code without regard for types, potentially making code clearer and reusable.
My programming philosophy is to understand the original purpose and design of the language and it's features in order to really appreciate the language. I feel template metaprogramming is bastardization of templates and should be avoided. Templates are however useful for defining higher level generic types such as the case of Tuples.