0

I am getting linker error, for the following code. I want to know how do I initialize stl map

#include <iostream>
#include <map>
#include <string>

class Test {
public:
  Test() {
  }
  static void setSerializer(void* fnptr, std::string className) {
    m_registry.insert(std::make_pair(className, fnptr));
  }
  static void* getSerializer(std::string className) {
    return m_registry.find(className)->second;
  }
private:
  static std::map<std::string, void*> m_registry;
};

void fn() {
}

int main() {
  Test::setSerializer(&fn,"abc");
  return 0;
}
Avinash
  • 12,851
  • 32
  • 116
  • 186
  • possible duplicate of [Defining static members in C++](http://stackoverflow.com/questions/3536372/defining-static-members-in-c) – iammilind Nov 16 '12 at 07:10
  • possible duplicate of [Initializing private static members](http://stackoverflow.com/questions/185844/initializing-private-static-members) – iammilind Nov 16 '12 at 07:11

2 Answers2

3

You need to define your static variable in class implementation - as you do for extern C++ variables. Just declaring it in class isn't sufficient! To do this put the code below to the .cpp file:

std::map<std::string, void*> Test::m_registry;
eraxillan
  • 1,552
  • 1
  • 19
  • 40
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
2

You need to initialize your static member in .cpp file. Normally we declare class in .h file and put definition into .cpp file. I did a bit enhancement to your code as shown below:

Test.h

class Test 
{
public:
  Test() { }
  static void setSerializer(std::string className, void* fnptr); // I swap the order of parameter. it makes more sense to have name and pointer pair
  static void* getSerializer(std::string className);

private:
  static std::map<std::string, void*> m_registry;
};

Test.cpp

std::map<std::string, void*> Test::m_registry;   // initialize static member here

void Test::setSerializer(std::string className, void* fnptr)
{
  m_registry.insert(std::make_pair(className, fnptr));
}

void* Test::getSerializer(std::string className) {    
  auto iter =  m_registry.find(className);   // check if iterator is valid 
  if (iter != m_registry.end() )
  {
    return (*iter).second;
  }
  return NULL;
}
billz
  • 44,644
  • 9
  • 83
  • 100