模板类与静态数据成员跨DLL/SO使用

template class with static data member used across DLL/SO

本文关键字:DLL SO 使用 数据成员 静态      更新时间:2023-10-16

假设我有这样一个模板类:

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

和我导出一个函数在d.l ll使用队列作为参数:

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中的弱符号能够解决这个问题吗?
非常感谢。

您不能按照您想象的方式将模板放入库中。您只能将实际的、实例化的类定义放在库中。

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

你可能想使用显式模板实例化来使编译器生成代码,并从头文件中取出静态成员定义:

// 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类的实例,因为他们不能访问静态成员,否则(即他们必须提供自己的)。