Does the C++ Standard actually mandate that templates must be instantiated at compile-time, not run-time?
If not, is it a convention that we use purely because it obviously makes sense to do it that way? Or is there some practical reason that would, theoretically, prevent an implementation from existing that can instantiate templates at run-time?
All the standard requires is that the observable behavior be as if the templates were instantiated before the program started to run. Any errors, for example, would have to trigger a message in some phase of the compilation, or at least before runtime. In theory, a compiler could probably defer full instantiation until runtime, but in practice, it would have to have done most of the work at compile time anyway, in order to be sure that any potential error messages appeared.
In a stricter sense, the standard considers “translation” as a unit; an implementation could, and implementations have (and I think some still do) defer instantiation until link time. Which leads to interesting questions when dynamic linking is involved. But the standard is silent about that: dynamic linking is really undefined behavior, as far as the standard is concerned, so it is up to the implementation.
In the end, however: instantiating templates is one of the most expensive operations a compiler does, and requires a very large and complex mechanism. Which no vendor wants to impose on an executable. So regardless of the loopholes, don’t expect to see run time instantiation any time soon. Especially as it wouldn’t buy you anything anyway: the standard requires that all templates can be instantiated at compile time, so you couldn’t instantiate a template somehow dependent on a runtime argument and still be standard conform.