强制在模板类中实例化静态成员

时间:2014-11-18 16:26:52

标签: c++ templates c++11 explicit-instantiation

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

以下是一个例子:

#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类型的对象进入&#34;注册表&#34;无论何时创建它们。从Y<T>派生的类X是一个模板类,应该实例化从其继承的每种类型的静态单例对象(使用奇怪的重复模板模式)。

这个想法是&#34;注册表&#34;将包含从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

所需的行为应该是一个A,一个B和一个C应该在注册表中。但它们都不是。问题是Y<T>::instance没有为任何类实例化,因为它没有在代码中使用。但是,我从不想使用这些字段,它们只是用来实例化单例。 那么有没有办法强制静态字段的实例化而不必向派生类添加额外的代码(即ABC)?< /强>

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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指针的注释仍然适用。