0

我想在模板类中使用静态成员来为从该模板类继承的每个类实例化一个单例对象。

这是一个例子:

#include <iostream>
#include <vector>

struct X{

    static std::vector<X*>& getRegistry(){
         static std::vector<X*> registry;
         return registry;
    }

    X(){
        getRegistry().push_back(this); // Each X adds itself to the registry
    }
};

template<typename T>
struct Y : X{ 
private:   
   static T instance; // The per-type singleton
};

template<typename T>
T Y<T>::instance {};

这个想法是,X无论何时创建类型的对象,它们都会将它们自己输入到“注册表”中。Y<T>派生的类X是一个模板类,它应该实例化从它继承的每种类型的静态单例对象(使用奇怪的重复模板模式)。

这个想法是“注册表”将包含每个类的一个对象,该对象继承自Y<T>. 这些类不需要做任何事情就可以添加到注册表中;相反,简单地继承Y<T>应该足以创建一个添加到注册表的单例对象。

我尝试了这样的代码:

struct A : Y<A>{};
struct B : Y<B>{};
struct C : Y<C>{};

int main(){
    std::cout << "Number of objects in the registry: " << X::getRegistry().size() << std::endl;
    // Should print "3"
}

小提琴链接:http: //ideone.com/aWDEg4

所需的行为应该是 one A、 oneB和 oneC应该在注册表中。但它们都不是。问题是Y<T>::instance没有为任何类实例化,因为它没有在代码中使用。但是,我从不想使用这些字段,它们只是用于实例化单例。那么有没有一种方法可以强制实例化静态字段而无需向派生类(即 、 和 )添加额外AB代码C

我知道我可以显式实例化template class Y<A>;,但这会给派生类添加额外的代码A

4

2 回答 2

1

您可以只创建静态实例:

struct A : Y<A>{};
struct B : Y<B>{};
struct C : Y<C>{};

static A a;
static B b;
static C c;

int main(){
    std::cout << "Number of objects in the registry: " << X::getRegistry().size() << std::endl; 
}

输出:

Number of objects in the registry: 3
于 2014-11-18T16:45:25.793 回答
0

我不认为你可以避免让客户参与Y,但你可以让Y' 的构造函数私有化,强制客户参与。例如,这可以按您的意愿工作:

template<typename T>
struct Y : X {
   Y(const Y<T> &other) {}
   static Y<T> create() { &instance; return Y<T>(); }
private:
   static T instance; // The per-type singleton
   Y() {}
};

template<typename T>
T Y<T>::instance {};

struct A : Y<A> { A() : Y(Y::create()) {} };
struct B : Y<B> { B() : Y(Y::create()) {} };
struct C : Y<C> { C() : Y(Y::create()) {} };

客户参与是其调用Y::create也恰好强制instance成员的实例化。当然,这可能不是您想要的,但它确实有效。this另请注意,即使您可以将静态实例添加到注册表,我之前关于指针的评论仍然适用。

于 2014-11-20T00:03:18.177 回答