title: automatic registration of object creator function with a macro
body: <p>Basically, I want to automatically register object creator functions with an object factory for a bunch of classes defined across many header files.</p>
  
  <p>The top answer to <a href="https://stackoverflow.com/questions/1310214/register-an-object-creator-in-object-factory">this post</a>, provides a solution -- but it doesn't fit my constraints.</p>
  
  <p>I'm working on an existing code base.  For the classes I need to register, there is already a macro following the class declarations that takes the class as a parameter.  If I were able to extend the existing macro definition to also do registration, then it would save a lot time because no existing code would have to be changed.</p>
  
  <p>The closest solution I've been able to come up with is creating a macro that defines a template specialization of a method that registers that object, then calls the previously defined template specialization method -- thus chaining all the register calls.  Then, when I want to register all classes, I just call the most recently defined specialization and it registers everything in reverse order of #include appearance.</p>
  
  <p>Below, I've posted a simple working example that shows my solution thus far.</p>
  
  <p>The only caveat is that I have no way of automatically keeping track of the last registered type to call in the chain.  So I keep redefining the #define LAST_CHAIN_LINK to be the most recently specialized typename.  This means that I'd have to add two lines of #undef/#define after every existing macro call -- I'd really like to avoid that.</p>
  
  <p>The main question:
  In the code below, is there any way to define the REGISTER_CHAIN macro to work without using the LAST_CHAIN_LINK #undef/#define code too?</p>
  
  <p>If only it were possible to redefine the LAST_CHAIN_LINK token inside the REGISTER_CHAIN method...</p>
  
  <p>My guess is some solution is possible using the <code>__COUNTER__</code> preprocessor feature, but that is not available on one of the target platforms (OS X using gcc 4.2.x) and thus not an option.</p>
  
  <p>Simplified example (compiles on GNU C++ 4.4.3):</p>
  
  <pre><code>#include &lt;map&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  
  struct Object{ virtual ~Object() {} }; // base type for all objects
  
  // provide a simple create function to derived classes
  template&lt;class T&gt; struct ObjectT : public Object {
    static Object* create() { return new T(); }
  };
  
  struct ObjectFactory {
    // pass in creator function pointer to register it to id
    static Object* create(const std::string&amp; id, Object* (*creator)() = 0) {
      static std::map&lt;std::string, Object* (*)()&gt; creators;
      return creator &amp;&amp; (creators[id] = creator) ? 0 : creators.find(id) != creators.end() ? (*creators.find(id)-&gt;second)() : 0;
    }
    template&lt;class T = int&gt; struct Register { static void chain() {} };
  };
  
  
  #define LAST_CHAIN_LINK // empty to start
  
  #define REGISTER_CHAIN(T)                               \
    template&lt;&gt; void ObjectFactory::Register&lt;T&gt;::chain()   \
    {                                                     \
      ObjectFactory::create(#T, T::create);               \
      std::cout &lt;&lt; "Register&lt;" &lt;&lt; #T &lt;&lt; "&gt;::chain()\n";   \
      ObjectFactory::Register&lt;LAST_CHAIN_LINK&gt;::chain();  \
    }
  
  struct DerivedA : public ObjectT&lt;DerivedA&gt; { DerivedA() { std::cout &lt;&lt; "DerivedA constructor\n"; } };
  REGISTER_CHAIN(DerivedA);
  // Can these next two lines be eliminated or folded into REGISTER_CHAIN?
  #undef LAST_CHAIN_LINK
  #define LAST_CHAIN_LINK DerivedA
  
  struct DerivedB : public ObjectT&lt;DerivedB&gt; { DerivedB() { std::cout &lt;&lt; "DerivedB constructor\n"; } };
  REGISTER_CHAIN(DerivedB);
  // Can these next two lines be eliminated or folded into REGISTER_CHAIN?
  #undef LAST_CHAIN_LINK
  #define LAST_CHAIN_LINK DerivedB
  
  struct DerivedC : public ObjectT&lt;DerivedC&gt; { DerivedC() { std::cout &lt;&lt; "DerivedC constructor\n"; } };
  REGISTER_CHAIN(DerivedC);
  // Can these next two lines be eliminated or folded into REGISTER_CHAIN?
  #undef LAST_CHAIN_LINK
  #define LAST_CHAIN_LINK DerivedC
  
  struct DerivedD : public ObjectT&lt;DerivedD&gt; { DerivedD() { std::cout &lt;&lt; "DerivedD constructor\n"; } };
  REGISTER_CHAIN(DerivedD);
  // Can these next two lines be eliminated or folded into REGISTER_CHAIN?
  #undef LAST_CHAIN_LINK
  #define LAST_CHAIN_LINK DerivedD
  
  int main(void)
  {
    // Call last link in the register chain to register all object creators
    ObjectFactory::Register&lt;LAST_CHAIN_LINK&gt;::chain();
    delete ObjectFactory::create("DerivedA");
    delete ObjectFactory::create("DerivedB");
    delete ObjectFactory::create("DerivedC");
    delete ObjectFactory::create("DerivedD");
    return 0;
  }
  </code></pre>
  
  <p>example output:</p>
  
  <pre><code>&gt; g++ example.cpp &amp;&amp; ./a.out
  Register&lt;DerivedD&gt;::chain()
  Register&lt;DerivedC&gt;::chain()
  Register&lt;DerivedB&gt;::chain()
  Register&lt;DerivedA&gt;::chain()
  DerivedA constructor
  DerivedB constructor
  DerivedC constructor
  DerivedD constructor
  </code></pre>