C++ is considered statically typed. I understand that.
I don’t understand how that applies to templates.
Here is a simple example of a type that cannot be determined at compile time:
template <typename... t>
struct foo {
using type = typename foo<t..., t...>::type;
};
foo<int>::type x; // type of x cannot be determined without running meta-program
I presume there are cases where it’s impossible to detect type errors without solving the halting problem.
So my question is, why aren’t templates considered dynamically typed?
Static/dynamic typing typically refers to the behavior at runtime of the final compiled program, not of the meta-program. Since
foo<int>::typeis resolved by the time you reach runtime of the final compiled program, it’s considered statically typed.As for the template metaprogram, one could consider it to be using duck typing, which is a kind of dynamic typing. Note, however, that there are still static types (in pre-C++11) – the number of template arguments on a template can be considered a meta-type for a meta-function that produces a concrete type (which is a value as far as the meta-program is concerned).
By comparison, in Haskell, they have a concept of a hierarchy of types. You have typical types – things like functions, integers, etc. Then you have ‘kinds’, which describe types and meta-functions on types. For example, the Haskell kind
* -> * -> *could refer to a mapping of keys to values, much like atemplate<typename Key, typename Value> class Mapin C++. Any determination on whether the language is statically or dynamically typed then would have to refer to which level of the hierarchy you’re referring to. Historically, C++ templates were never really thought of as meta-programs when they were first designed, so this kind of terminology isn’t as widely used in C++, but the same concepts can still be applied.