In C++, if you define this function in header.hpp
void incAndShow()
{
static int myStaticVar = 0;
std::cout << ++myStaticVar << " " << std::endl;
}
and you include header.hpp in at least two .cpp files. Then you will have multiple definition of incAndShow(). Which is expected. However, if you add a template to the function
template <class T>
void incAndShow()
{
static int myStaticVar = 0;
std::cout << ++myStaticVar << " " << std::endl;
}
then you won’t have any multiple definition of error. Likewise, two different .cpp calling the function with the same template (e.g. incAndShow<int>()), will share myStaticVar. Is this normal? I’m asking this question, because I do rely on this “feature” (sharing the static variable) and I want to be sure that it is not only my implementation that is doing this.
You can rely on this. The ODR (One Definition Rule) says at
3.2/5in the Standard, whereDstands for the non-static function template (cursive font by me)Of the last four requirements, the two most important are roughly
Edit
I figure that this alone is not sufficient to guarantee that your static variables in the different instantiations are all the same. The above only guarantees that the multiple definitions of the template is valid. It doesn’t say something about the specializations generated from it.
This is where linkage kicks in. If the name of a function template specialization (which is a function) has external linkage (
3.5/4), then a name that refers to such a specialization refers to the same function. For a template that was declared static, functions instantiated from it have internal linkage, because ofIf the function template wasn’t declared with static, then it has extern linkage (that, by the way, is also the reason that we have to follow the ODR at all. Otherwise,
Dwould not be multiply defined at all!). This can be derived from14/4(together with3.5/3)Finally, we come to the conclusion that a function template specialization generated from a function template with external linkage has itself external linkage by
3.5/4:And when it has internal linkage was explained by
3.5/3for functions provided by explicit specializations, and14/4for generated specializations (template instantiations). Since your template name has external linkage, all your specializations have external linkage: If you use their name (incAndShow<T>) from different translation units, they will refer to the same functions, which means your static objects will be the same in each occasion.