It is well-known that static
variables of a routine, function, or method ("member function") exist for each unique instantiation.
(Quick review and sanity check.)
In the common case, this is exactly one variable:
int f() {
static int i = 0;
return i++;
}
That is, there is a single variable i
that is created in .BSS/.DATA that "belongs" to the function f
. For templates, it's one per unique instantiation:
template <typename T> int f() {
static int i = 0;
return i++;
}
int g() {
return f<int>() + f<int>() + f<int>() + f<float>();
}
Here, there are two unique instantiations (f<int>
and f<float>
), and so there are two i
s in the .BSS/.DATA segment.
Problem
I want some way to make variables in template member functions live both per-instance and per-instantiation of their enclosing class. I am interested in achieving this EFFECT, by more-or-less any performant means necessary (possibly not involving static at all). How should I do this?
For example:
class Foo { public:
template <typename T> int f() {
static int i = 0;
return i++;
}
};
void g() {
Foo foo1;
Foo foo2;
/*
These will have values a=0, b=0, c=1. This happens because there are two
variables:
"Foo::f<float>()::i"
"Foo::f<double>()::i"
What I *want* is for there to be three variables:
"Foo::f<float>()::i" (foo1's copy)
"Foo::f<float>()::i" (foo2's copy)
"Foo::f<double>()::i" (foo1's copy)
So the result is a=0, b=0, c=0. How can I accomplish this effect (maybe
not using static)?
*/
int a = foo1.f<float>();
int b = foo1.f<double>();
int c = foo2.f<float>();
}