0

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?

OMGtechy
  • 7,935
  • 8
  • 48
  • 83

1 Answers1

4

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).

OMGtechy
  • 7,935
  • 8
  • 48
  • 83
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055