在我的 DLL 中,我有一个类模板和从该模板的实例派生的第二个类。这两个类都应导出并在其他 DLL 中使用。编译器是 Visual Studio 2013。我希望模板代码在一个翻译单元中被实例化,所以我使用显式实例化。
DLL1 中的代码分布如下。基类模板:
// In BaseTemplate.h:
#pragma once
template<typename T>
class BaseTemplate
{
public:
T foo(T t);
};
// declare explicit instantiation
extern template class BaseTemplate < int >;
// In BaseTemplate.cpp:
#include "BaseTemplate.h"
// template method definition
template<class T>
T BaseTemplate<T>::foo(T t)
{
return t;
}
// explicit instantiation and export
template class __declspec(dllexport) BaseTemplate < int >;
派生类:
// In Derived.h:
#pragma once
#include "BaseTemplate.h"
#ifdef DLL1_EXPORTS // this is predefined in DLL1
#define DLL1_API __declspec(dllexport)
#else
#define DLL1_API __declspec(dllimport)
#endif
class DLL1_API Derived : public BaseTemplate < int >
{
public:
void bar();
};
理论是extern语句阻止在所有翻译单元中实例化,除了 BaseTemplate.cpp,其中执行显式实例化。但是,我收到以下警告(在我的项目中被视为错误,因此会破坏构建):
1> basetemplate.h(19): warning C4661: 'int BaseTemplate<int>::foo(T)' :
1> no suitable definition provided for explicit template instantiation request
1> with
1> [
1> T=int
1> ]
1> basetemplate.h(15) : see declaration of 'BaseTemplate<int>::foo'
似乎派生类的导出触发了实例化,忽略了extern语句。如果我从 Derived 类中删除导出宏,则 DLL1 编译时不会发出警告(但其他 DLL 显然无法链接)。如果我在 Derived 类中聚合 BaseTemplate 类型的成员而不是继承,它也可以正常工作(即使是导出)。
如何在 Visual Studio 中组合显式模板实例化和导出的派生类?