具有跨 DLL/SO 使用的静态数据成员的模板类

Bai*_*ang 4 c++ static templates export

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

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

template <class T> int Queue<T>::Size = 0;
Run Code Online (Sandbox Code Playgroud)

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

void ChangeQueueSize(Queue<int>& q)
{
    q.Size = 100;
}
Run Code Online (Sandbox Code Playgroud)

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

Queue<int> q;

q.Size = 10; 

ChangeQueueSize(q);

int updatedSize = q.Size;
Run Code Online (Sandbox Code Playgroud)

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

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

我们能做些什么来解决这个问题呢?
gcc 中的弱符号能够解决这个问题吗?
非常感谢。

Ker*_* SB 5

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

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

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

// 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>;
Run Code Online (Sandbox Code Playgroud)

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

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