Today, someone presented me with code of the following form:
#include <iostream>
namespace example {
template <typename T>
T variable_template = T(42);
}
int main() {
example::variable_template<int> = 10;
std::cout << example::variable_template<int> << std::endl;
}
You can see it running here: http://coliru.stacked-crooked.com/a/3a786c42b5204b0a
I expected this code to print 42, since 10 appears to be assigned to a temporary. Inside the namespace, there template is only a declaration (not an instantation), so there's no data to mutate inside of the namespace. Dispite that, it surprised me and printed 10 instead.
I would have also expected a warning on the assignment to a temporary, but that didn't happen either.
Is this undefined behaviour, is my understanding of templates flawed, or is something else going on?
Inside the namespace, there template is only a declaration (not an instantation), so there's no data to mutate inside of the namespace.
Not so!
[C++14: 14.7.2/6]:
An explicit instantiation of a class, function template, or variable template specialization is placed in the namespace in which the template is defined. [..]
When you have a class template Foo
, and refer to an instantiation (say, Foo<int>
), that instantiation exists just like a normal class, with the same scope as the template had.
There is nothing different with variable templates. When you refer to example::variable_template<int>
, you "add" that variable to the scope containing the template.
Your namespace example
then contains a variable called variable_template<int>
.
I would have also expected a warning on the assignment to a temporary, but that didn't happen either.
There are no temporaries here, aside from the T(42)
.