2

我有一个其他 C++ 项目常用的 C++ 类库项目。为了能够在我的类库项目中使用类,我编写了一个头文件,如下例所示

#pragma once
#ifdef MYLIB
# define MYLIB_EXPORT __declspec(dllexport)
#else
# define MYLIB_EXPORT __declspec(dllimport)
#endif

在我想在我的类库项目中创建一个模板类之前没问题。问题是我无法导出我的模板类。

我的类.h

template<class T>
class MYLIB_EXPORT MyClass
{
    void myMethod();
    // ...
}

template<class T>
void MyClass::myMethod()
{
    // ...
}

在这种情况下,我收到编译错误,提示“不允许定义 dllimport 函数”。我知道导致问题的原因并且我理解它。使用我的类库项目的其他项目将 MYLIB_EXPORT 关键字转换为 __declspec(dllimport)。因此,他们期望 MyClass 的方法在 DLL 中定义。但是,编译器会在头文件中看到定义。

如何克服这种情况并能够导出在我的类库项目中定义的模板类?

4

2 回答 2

4

未实例化的模板不能直接编译——它们是代码生成器,所以它们实际上只有在实例化时才被翻译成二进制指令;因此,您不能将模板“以二进制形式”导出,就好像它是“常规”函数/类一样(另一方面,至少在理论上您可以导出模板的实例化)。

长话短说:只需将模板留在标题中以供图书馆客户包含。

请注意,这正是您将模板保留在标头中并且通常不会将它们的实现分离到文件中的确切原因.cpp

于 2012-12-04T14:45:37.610 回答
0

只需删除MYLIB_EXPORT模板类上的语句。然后您可以在类之外定义类函数(但仍然在*.h*.hpp头文件中)。

我的类.h

    template <typename T>
    class MyClass    // MYLIB_EXPORT removed
    {
        void myMethod();
        // ...
    };

    template <typename T>
    void MyClass<T>::myMethod()
    {
        // ...
    }

我得到了这个问题。很长一段时间后,我意识到删除 MYLIB_EXPORT 修复了它。希望这个答案可以为其他人节省时间:-)

于 2013-04-12T14:15:36.733 回答