I'm looking for an abstract factory for class templates, where the classes register themselves automatically at static initialization time. For regular (non-templated) classes, the solution is straightforward enough using static members. Here's an example of a (rather simplistic) solution that works just fine:

#include <cassert>
#include <iostream>

class Base {
 public:
  virtual size_t id() const = 0;
  virtual const char* name() const = 0;
  virtual ~Base() {}
};

typedef Base* (*CreateFunc)(void);

class SimpleFactory {
 private:
  static const size_t NELEM = 2;
  static size_t id_;
  static CreateFunc creators_[NELEM];

 public:
  static size_t registerFunc(CreateFunc creator) {
    assert(id_ < NELEM);
    assert(creator);
    creators_[id_] = creator;
    return id_++;
  }

  static Base* create(size_t id) { assert(id < NELEM); return (creators_[id])(); }
};

size_t SimpleFactory::id_ = 0;
CreateFunc SimpleFactory::creators_[NELEM];


class D1 : public Base {
 private:
  static Base* create() { return new D1; }
  static const size_t id_;

 public:
  size_t id() const { return id_; }
  const char* name() const { return "D1"; }
};

const size_t D1::id_ = SimpleFactory::registerFunc(&create);

class D2 : public Base {
 private:
  static Base* create() { return new D2; }
  static const size_t id_;

 public:
  size_t id() const { return id_; }
  const char* name() const { return "D2"; }
};

const size_t D2::id_ = SimpleFactory::registerFunc(&create);

int main() {
  Base* b1 = SimpleFactory::create(0);
  Base* b2 = SimpleFactory::create(1);
  std::cout << "b1 name: " << b1->name() << "\tid: " << b1->id() << "\n";
  std::cout << "b2 name: " << b2->name() << "\tid: " << b2->id() << "\n";
  delete b1;
  delete b2;
  return 0;
}

The question I have is how to make it work when the stuff I want to register/create is more like:

Edit
Report