"Compile time polymorphism" used to signify function overloading.
It only applies to functions because that's all you can overload.
Templates in modern C++ modify this.
One example has previously been provided by Neil Butterworth.
Another technique is template specialisation.
As an example:
#include <iostream>
#include <string>
template <class T>
struct my_template {
T foo;
my_template() : foo(T()) {}
};
template <>
struct my_template<int> {
enum { foo = 42 };
};
int main() {
my_template<int> x;
my_template<long> y;
my_template<std::string> z;
std::cout << x.foo << "\n";
std::cout << y.foo << "\n";
std::cout << "\"" << z.foo << "\"";
return 0;
}
This should return 42, 0, and "" (an empty string) – we're receiving a struct that behaves differently depending on the type.
Instead of functions, we have "compile time polymorphism" of classes.
You might argue that this is at least partially the effect of the function Object() { [native code] } (a function) in at least one example, but the specialised form of my template doesn't even have a function Object() { [native code] }.
Edit: To clarify why this is polymorphism.
I placed "compile time polymorphism" in quotes since it differs from standard polymorphism.
Nonetheless, the result is identical to what we would expect from overloading functions:
int value(int x) { return 0; }
long value(long x) { return 42; }
std::cout << value(1);
std::cout << value(1L);
Function overloading and specialisation have comparable results.
I agree that it's debatable whether "polymorphism" applies to either, but I believe it does in roughly equal measure to both.