力模板静态成员实例

Force template static member instantiation

本文关键字:实例 静态成员      更新时间:2023-10-16

我正在尝试创建仅在实例化模板时执行某些代码的程序(它将用于低级驱动器初始化(。现在我有以下解决方案。

class Initializer
{
public:
    Initializer(){
        // This code is executed once
    }
    void silly() const{
    }
};
template <class T>
class Proxy{
protected:
    static const Initializer init;
};
template<class T>
const Initializer Proxy<T>::init;
template<class T>
class MyTemplate : public Proxy<void>{
public:
    static void myMethod1(){
        init.silly();
        // ... Something useful
    }
    static void myMethod2(){
        init.silly();
        // ... Something useful
    }
};

Initializer默认构造函数仅在我调用myMethod1()myMethod2()的某个地方执行。

但是有没有办法摆脱这些init.silly();行?

您的问题是,除非引用模板的成员,否则不会实例化。

而不是调用init.silly(),您只能引用成员:

    static void myMethod1(){
        (void)init;
        // ... Something useful
    }

或,如果您希望init绝对定义,则可以明确实例化:

template<>
const Initializer Proxy<void>::init{};

模板和低级驱动器初始化?

您可以做类似的事情:

class Initializer
{
public:
    Initializer() {
        // This code is executed once
    }
};
template <class T>
class Proxy {
protected:
    Proxy()
    {
        static Initializer init;
    }
};
template<class T>
class MyTemplate : public Proxy<void> {
public:
    void myMethod1() {
        // ... Something useful
    }
    void myMethod2() {
        // ... Something useful
    }
};

您的所有代码仅使用静态功能,并没有真正显示为什么使用类和模板。通过我的更改,我制作了myMethod1myMethod2非静态和代理((构造函数将创建Initializer一次。

请注意,由于所有模板,您的Initializer可能会像实例化代理模板一样多次执行。你真的是说吗?如果没有,请将其转换为没有意外结果的清晰可读代码。对于其他人来说,这也将更好地维护和可读性:

class Initializer
{
    Initializer() {
        // This code is executed once
    }
public:
    void init()
    {
        static Initializer init;
    }
};

template<class T>
class MyTemplate {
public:
    static void myMethod1() {
        Initializer::init();
        // ... Something useful
    }
    static void myMethod2() {
        Initializer::init();
        // ... Something useful
    }
};

这绝对可以清楚地表明,Initializer仅在调用myMethod1myMethod2之前创建一次。如果没有任何调用您的Initializer::init,则应在链接时间删除Initializer的代码。