Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template static member instantiation

#include <map>
#include <iostream>
template <typename T>
class A 
{
 static std::map<int, int> data;
public:
 A()
 {
  std::cout << data.size() << std::endl;
  data[3] = 4;
 }
};

template <typename T>
std::map<int, int> A<T>::data;

//std::map<int, int> A<char>::data;

A<char> a;

int main()
{
 return 0;
}

What is wrong with this? Without explicit instantiation it breaks at

 data[3] = 4; 
Explicit instantiation solves the problem but the program breaks after
std::cout << data.size() << std::endl;
what means that the static class template memeber data was instantiated.
like image 322
mrs Avatar asked Sep 13 '10 22:09

mrs


2 Answers

There is no explicit instantiation in your code.

There is no order of initialization of instantiated static data members among other static data members. So your code has effectively undefined behavior: Depending on whether the compiler first initializes the map or a, the reference to the map is valid or not.

See C++ Static member initialization.

like image 128
Johannes Schaub - litb Avatar answered Sep 19 '22 12:09

Johannes Schaub - litb


I don't have Visual C++ handy, but I can see the same problem with your code compiling with GCC. You need the initialize the data member:

template<> std::map<int, int> A<char>::data = std::map<int, int>();

With this change, it compiles and runs correctly (for me on GCC on Linux).

like image 41
Jack Lloyd Avatar answered Sep 18 '22 12:09

Jack Lloyd