c++templatesvariable-templates

Can a variable template be mutated?


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?


Solution

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