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?
Not so!
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 calledvariable_template<int>
.There are no temporaries here, aside from the
T(42)
.