如何在stl模板中使用导出的类(__declspec(dllexport))?

Atu*_*tul 4 c++ templates dllexport

我正在使用导出的类

class __declspec(dllexport) myclass  
{  
private:  
template __declspec(dllexport) class std::map<myclass*,int>;    
std::map<myclass*,int>m_map;  
//something  
};    
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我得到一个警告C4251说m_map:类'std :: map <_Kty,_Ty>'需要让dll接口供myclass类的客户端使用.
关于我如何解决这个问题的任何想法?
阿图尔

Cas*_*Cow 6

您不应该将__declspec(dllexport)用于使用您的DLL将使用的代码的头文件,因为它们需要使用__declspec(dllimport).

因此,如果设置了特定的其他定义,则应创建使用dllexport的宏,如果不设置,则应创建dllimport.

在某个公共标题中:

#ifdef EXPORTING_FOO
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif
Run Code Online (Sandbox Code Playgroud)

您可以实例化模板:

extern template class FOO_API Templ<MyClass, int >;
Run Code Online (Sandbox Code Playgroud)

在包含的标题内.注意这里的extern.在一个编译单元内声明相同但没有extern且没有FOO_API,因此:

template class Templ<MyClass, int >;
Run Code Online (Sandbox Code Playgroud)

这意味着使用您的库的代码不会实例化模板,而是使用库中的模板.当模板具有虚拟成员时,这尤其有用.

如果模板是标准库或boost中的模板,则使用您的模板的代码必须使用与您相同的版本,否则可能会出现严重问题.

鉴于在您自己的示例中,它出现在私有区域中,建议您将其重构为库的接口.理想情况下,您的库只应公开除前向声明之外的公共方法和成员.私有拷贝构造函数和赋值是为了使一个类不可复制和不可赋值是可以的 - 它们实际上并不是它们属于你的类接口的实现的一部分(你说你不能复制或分配它们) ).