模板类,在DLL / SO中使用静态数据成员

时间:2011-07-12 14:57:37

标签: c++ templates static export

假设我有这样的模板类:

template <class T>
class Queue
{
public:
    static int Size;
};

template <class T> int Queue<T>::Size = 0;

我在D.dll中导出一个函数,使用Queue作为参数:

void ChangeQueueSize(Queue<int>& q)
{
    q.Size = 100;
}

然后我在A.exe中使用这个导出的函数:

Queue<int> q;

q.Size = 10; 

ChangeQueueSize(q);

int updatedSize = q.Size;

由于Queue类是从2个项目中的类模板生成的,因此实际上有2个代码副本以及静态数据成员。

因此调用ChangeQueueSize不会真正改变队列大小,它只是更新另一个类的静态成员,它恰好具有相同的类名。

我们可以做些什么来解决这个问题? gcc中的弱符号是否能解决这个问题?
非常感谢。

1 个答案:

答案 0 :(得分:4)

您无法以您想象的方式将模板放入库中。您只能将实际的实例化类定义放在库中。

模板本质上是一种代码生成工具,您只能将生成的代码放入库中。

您可能希望使用显式模板实例化来使编译器生成代码,并从标题中取出静态成员定义

// Header, shipped to clients
template <class T>
class Queue
{
public:
    static int Size;
};

// Library source code:
template <typename T> int Queue<T>::size = 0;

template class Queue<int>;

现在将源文件编译到库中;这将包含静态成员变量Queue<int>::size的实例。

请注意,您的消费者只能使用T = int类的实例,因为他们无法访问静态成员(即他们必须自己提供)。