繁体   English   中英

强制模板静态成员实例化

[英]Force template static member instantiation

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

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
    }
};

只有在我调用myMethod1()myMethod2()情况下,才会执行Initializer默认构造函数。

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

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

您可以只引用该成员,而不是调用init.silly()

    static void myMethod1(){
        (void)init;

        // ... Something useful
    }

或者,如果您希望绝对定义init ,则可以显式实例化它:

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

模板和低级驱动程序初始化?..我试着尽可能使它成为C :)以确保确切的行为。

您可以这样做:

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非静态,而Proxy()构造函数将创建一次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
    }
};

这清楚地表明,只有在调用myMethod1myMethod2之前,才会创建一次Initializer 如果没有任何东西调用您的Initializer::init那么应该在链接时删除Initializer中的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM