最好的方法来让C ++类型在列表中自我注册? [英] Best way to for C++ types to self register in a list?

查看:113
本文介绍了最好的方法来让C ++类型在列表中自我注册?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一些每类数据:(AandB.h)

Suppose I have some per-class data: (AandB.h)

class A
{
public:
   static Persister* getPersister();
}

class B
{
public:
   static Persister* getPersister();
}

...和很多很多类。我想做一些类似的事情:

... and lots and lots more classes. And I want to do something like:

persistenceSystem::registerPersistableType( A::getPersister() );
persistenceSystem::registerPersistableType( B::getPersister() );
...
persistenceSystem::registerPersistableType( Z::getPersister() );

...每个类别。

我的问题是:是否有一种方法来自动构建每类型数据的列表,以便我不必枚举每个类型在一个大块(如上面的例子)?

My question is: is there a way to automate building a list of per-type data so that I don't have to enumerate each type in a big chunk (as in the above example)?

例如,您可以这样做的一种方法是:(AutoRegister.h)

For example, one way you might do this is: (AutoRegister.h)

struct AutoRegisterBase
{
   virtual ~AutoRegisterBase() {}
   virtual void registerPersist() = 0;
   static AutoRegisterBase*& getHead()
   {
      static AutoRegisterBase* head= NULL;
      return head;
   }

   AutoRegisterBase* next;
};

template <typename T>
struct AutoRegister : public AutoRegisterBase
{
   AutoRegister() { next = getHead(); getHead() = this; }

   virtual void registerPersist()
   {
       persistenceSystem::registerPersistableType( T::getPersister() );
   }
};

并使用如下:(AandB.cxx:)

and use this as follows: (AandB.cxx: )

static AutoRegister<A> auto_a;
static AutoRegister<B> auto_b;

现在,我的程序启动后,我可以安全地执行:(main.cxx)

Now, after my program starts, I can safely do: (main.cxx)

int main( int, char ** )
{
    AutoRegisterBase* p = getHead();
    while ( p )
    {
        p->registerPersist();
        p = p->next;
    }
    ...
}

的每个类型的数据,并将它们全部注册在一个大列表中的某个地方,迂回以后使用。

to collect each piece of per-type data and register them all in a big list somewhere for devious later uses.

这种方法的问题是需要在每个类型的某处添加一个AutoRegister对象。 (即它不是非常自动的,并且容易忘记做)。模板类怎么样?我真正想要的是模板类的实例化以某种方式导致该类自动注册在列表中。如果我能做到这一点,我可以避免让类的用户(而不是作者)记住创建一个:

The problem with this approach is that requires me to add an AutoRegister object somewhere per type. (i.e. its not very automatic and is easy to forget to do). And what about template classes? What I'd really like is for the instantiation of a template class to somehow cause that class to get automatically registered in the list. If I could do this I would avoid having to have the user of the class (rather than the author) to remember to create a:

static AutoRegister< SomeClass<X1> > auto_X1;
static AutoRegister< SomeClass<X2> > auto_X2;
...
etc....

对于FIW,我怀疑没有解决方案。

For FIW, I suspect there's no solution to this.

推荐答案

p>如果模板的实例化,你可以在main之前执行一次。诀窍是将静态数据成员放入类模板,并从外部引用。静态数据成员触发的副作用可以用于调用寄存器函数:

You can execute something before main once if a instantiation of a template is made. The trick is to put a static data member into a class template, and reference that from outside. The side effect that static data member triggers can be used to call the register function:

template<typename D>
struct automatic_register {
private:
    struct exec_register {
        exec_register() {
            persistenceSystem::registerPersistableType(
                D::getPersister()
            );
        }
    };
    // will force instantiation of definition of static member
    template<exec_register&> struct ref_it { };

    static exec_register register_object;
    static ref_it<register_object> referrer;
};

template<typename D> typename automatic_register<D>::exec_register 
    automatic_register<D>::register_object;

automatic_register< YourClass> 。寄存器函数将在main之前被调用,当 referrer 的声明被实例化时(当该类派生自时,会隐式地从模板中实例化该类)。

Derive the class you want to be auto-registered from automatic_register<YourClass> . The register function will be called before main, when the declaration of referrer is instantiated (which happens when that class is derived from, which will implicitly instantiate that class from the template).

有一些测试程序(而不是注册函数,调用do_it函数):

Having some test program (instead of the register function, a function do_it is called):

struct foo : automatic_register<foo> {    
    static void do_it() {
        std::cout << " doit "; 
    } 
}; 

int main() { 
    std::cout << " main "; 
}

产生此输出(如预期):

Yields this output (as expected):

doit main

这篇关于最好的方法来让C ++类型在列表中自我注册?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆