I understand that the non-type template parameter should be a constant integral expression. Can someone shed light why is it so ?
template <std::string temp>
void foo()
{
// ...
}
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.
I understand what a constant integral expression is. What are the reasons for not allowing non-constant types like std::string
as in the above snippet ?
A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be:
Also, string literals are objects with internal linkage, so you can't use them as template arguments. You cannot use a global pointer, either. Floating-point literals are not allowed, given the obvious possibility of rounding-off errors.
The reason you can't do this is because non-constant expressions can't be parsed and substituted during compile-time. They could change during runtime, which would require the generation of a new template during runtime, which isn't possible because templates are a compile-time concept.
Here's what the standard allows for non-type template parameters (14.1 [temp.param] p4):
That is not allowed.
However, this is allowed:
See §14.1/6,7,8 in C++ Standard (2003).
Illustration:
Output:
You need to be able to mangle template arguments
Now an impl would need to come up with a unique sequence of characters for a
std::string
or, for that matter, any other arbitrary user defined class, storing a particular value, the meaning of which is not known to the implementation. And in addition, the value of arbitrary class objects can't be calculated at compile time.It's planned to consider allowing literal class types as template parameter types for post-C++0x, which are initialized by constant expressions. Those could be mangled by having the data members recursively mangled according to their values (for base classes, for example we can apply depth-first, left-to-right traversal). But it's definitely not going to work for arbitrary classes.