views:

184

answers:

2
#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.

A: 

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).

Jack Lloyd
Is this needed because a separate instance of data is needed for each template initialized with a different type, in this char
siri
+2  A: 

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.

Johannes Schaub - litb
I was trying std::vector instead of map and everything worked fine without explicit instantiation - you think that it is just luck?
mrs
and that is funny that in this example the first line in constructor std::cout << data.size() << std::endl; works as expected; the program breaks when I try to insert something into the map
mrs
That "explicit instantiation" is not an explicit instantiation. It's the definition of a static data member called `data` of an explicit specialization of the template `A` for `T = char`. There is no such explicit specialization. The compiler has to emit an error message for that code (if you comment it in).
Johannes Schaub - litb