【问题标题】:Template Specializations and Static Locals模板专业化和静态本地化
【发布时间】:2012-01-29 07:24:27
【问题描述】:

我有一个 X 课...

class X {...}

我想为一组类型的每个不同类型创建一个 X 实例。 (其中一些类型不是类和/或不是我编写的。)

为此我想到了:

template<typename T> X& XT();

然后对于每种类型 A、B 和 C:

template<> X& XT<A>() { static X x; return x; }
template<> X& XT<B>() { static X x; return x; }
template<> X& XT<C>() { static X x; return x; }

这行得通吗?这是最好的方法吗?有哪些替代方法?

【问题讨论】:

  • 这很聪明。我想不出它为什么不起作用的任何原因。
  • 对我来说,问题还不清楚。
  • 你心目中的“本地”这个词指的是什么?
  • @KerrekSB:可能是本地的。
  • 来自标准:“在块范围内声明的变量是局部变量”C++11 3.3.3

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


【解决方案1】:

您不需要专门化该功能。你可以这样做:

template<typename T> 
X& XT() 
{ 
    static X x; 
    return x; 
}

并将其用作:

X &xa = XT<A>();
X &xb = XT<B>();
X &xc = XT<C>();
X &xd = XT<A>(); //xd is same as xa

xaxbxc 这三个对象都是 X 的不同实例。但是,xaxd 是相同的实例,因为它们都调用相同的函数。

这里要注意的一点是编译器为每个不同的模板参数实例化不同的函数。所以XT&lt;A&gt;() 是与XT&lt;B&gt;() 不同的函数,每个函数都有自己的自己的 static 局部变量。所以XT&lt;A&gt;() 中的static 局部变量与XT&lt;B&gt;() 中的变量是不同的实例。

【讨论】:

    【解决方案2】:

    您甚至不需要单独定义每个:

    #include <iostream>
    
    template<typename T, typename X>
    struct static_holder {
        static T static_instance;
    };
    
    template<typename T, typename X>
    T static_holder<T,X>::static_instance;
    
    template<typename T, typename X>
    T &get_static_instance() {
        return static_holder<T,X>::static_instance;
    }
    

    现在你可以定义:

    template<typename K>
    X &XT() {
        return get_static_instance<X, K>();
    }
    

    请注意,如果跨共享库边界使用此技术可能会失败。

    【讨论】:

    • 在 linux 中它将跨共享库边界正常工作。我相信在 Windows 中你需要用 dllexport 或其他东西做一些特别的事情。
    • @JohannesSchaub-litb,我在 solibs 中遇到过此类问题 - 模板很好,但您会发现符号不会被重复数据删除。在我的情况下,它是 RTTI 信息,但我怀疑它也与模板静态相同。
    猜你喜欢
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    相关资源
    最近更新 更多