I have the following code:
#include <cstdlib>
#include <cstdio>
#include <atomic>
enum ATYPE { Undefined = 0, typeA, typeB, typeC };
template<ATYPE TYPE = Undefined>
struct Object
{
Object() { counter++; }
static std::atomic<int> counter;
};
//template<ATYPE TYPE>
//std::atomic<int> Object<TYPE>::counter = 0;
template<ATYPE TYPE>
void test()
{
printf("in test\n");
Object<TYPE> o;
}
int main(int argc, char **argv)
{
test<typeA>();
printf("%d\n", Object<typeA>::counter.load());
return 0;
}
and when I compile it with the following command line:
clang++ -o test -std=c++11 -stdlib=libc++ test.cpp
I got the following error:
Undefined symbols for architecture x86_64:
"Object<(ATYPE)1>::counter", referenced from:
_main in testray-D4iTOH.o
Object<(ATYPE)1>::Object() in testray-D4iTOH.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have no idea if what I am trying to do is technically possible. As the code hopefully shows, I am trying to create a static instance of the atomic class (BTW, I have no idea how to initialize this variable either. How do you intialize a static std::atomic<>?). What I am trying to do is count the number of instances of the class Object created while running the program, for each possible type (typeA, B, C, etc.). That's the mechanism I came up with but maybe (beside the problem I have which I would like to fix if possible) someone could advice a better solution? It would be much appreciated.
Thank you so much.
As pointed by Dave in the comment, the static variable needs to be declared somewhere:
#include <cstdio>
#include <atomic>
enum ATYPE { Undefined = 0, typeA, typeB, typeC };
template<ATYPE TYPE = Undefined>
struct Object
{
Object() { counter++; }
static std::atomic<int> counter;
};
template<ATYPE TYPE>
std::atomic<int> Object<TYPE>::counter(0);
template<ATYPE TYPE>
void test()
{
printf("in test\n");
Object<TYPE> o;
}
int main(int argc, char **argv)
{
test<typeA>();
printf("%d\n", Object<typeA>::counter.load());
return 0;
}
It compiles fine.