Reputation: 40058
a template class has all static members replicated for each instanciation of it. If I want a static member that exists only once for all instanciations, what should I do? Use a normal static field outside of the class template? Would work, but seems unelegant since there is no more association to the template class. Is there a way to somehow associate such unique static member with a template class?
Upvotes: 2
Views: 1490
Reputation: 104698
Use a normal static field outside of the class template?
exactly; just plop it into a function outside of the template declaration.
if really want to restrict access in this scenario, you could use something like this:
class t_shared {
static int& Shared() {
static int s(0);
return s;
}
public:
template < typename T >
class t_template {
public:
void f() {
std::cout << ++Shared() << std::endl;
}
};
};
int main(int argc, const char* argv[]) {
t_shared::t_template<int>().f();
return 0;
}
Upvotes: 0
Reputation: 24412
Define some base class for the template class. Include in this base class all common members:
class ExampleBase {
public:
static int foo;
};
int ExampleBase::foo = 0;
template <class A>
class Example : private ExampleBase {
public:
static void setFoo(int f) { foo = f; }
static int getFoo() { return foo; }
};
Then each of Example instances has the common static member ExampleBase::foo
:
int main() {
Example<int>::setFoo(7);
assert(Example<float>::getFoo() == 7);
};
Upvotes: 1
Reputation: 477040
Class templates are actually a bit different from ordinary classes with respect to static members. The following is perfectly fine, even when foo.hpp
is included by every translation unit:
foo.hpp:
template <typename T> struct TmplFoo
{
static double d;
};
struct OrdFoo
{
static double e;
}
foo.cpp:
#include "foo.hpp"
double OrdFoo::e = -1.5;
Note that we never need a separate definition of TmplFoo<T>::d
. The linker knows how figure out that all local references to TmplFoo<T>::d
(for a given T
) refer to the same object.
Upvotes: -1
Reputation: 64223
Put a global variable somewhere.
Something like this :
#include <iostream>
// header.hpp
extern int someValue;
template< typename T >
struct A
{
int foo() const
{
return someValue;
}
};
// source.cpp
int someValue = 5;
int main()
{
std::cout << A< float >().foo() << std::endl;
std::cout << A< int >().foo() << std::endl;
}
Upvotes: 0
Reputation: 46667
No; each template class is a completely separate object.
What you could do is create a common ancestor class with the static member:
class Parent
{
public:
static int commonStatic;
};
template <typename T>
class MyTempl : public Parent
{
static int nonSharedStatic;
};
Upvotes: 5
Reputation: 258608
a template class has all static members replicated for each instanciation of it.
Nope. It has different statics for each specialization, but different specializations are different classes. Make no mistake about it, vector<int>
and vector<char>
are totally separate. Think of it as writing IntVector
and CharVector
.
EDIT: Don't use inheritance for this. Introducing a base class just so you can share a static member is definitely the wrong way to go.
If you want stuff shared between different classes, do it like you would usually do it. Wrap some statics in a third class and that's it.
Upvotes: 2