warning C4251: 'vectortemp::m_Vector' : class 'std::vector' needs to have dll-interface to be used by clients of class 'vectorte

症状:

在DLL中定义一个模板类并用__declspec(dllexport)定义。

   1: template<typename T, int d>
   2: class DLLExportExportMacro vectortemp
   3: {
   4: public:
   5:  
   6:     vector m_Vector;
   7:  
   8: public:
   9:     vectortemp(vector v):m_Vector(d)
  10:     {
  11:         if (v.size() == d)
  12:         {
  13:             m_Vector = v;
  14:         }
  15:         else
  16:             throw invalid_argument("Vector size does not match.");
  17:     }
  18:  
  19:     vectortemp(T v[]):m_Vector(d)
  20:     {
  21:         if (sizeof(v)/sizeof(T) == d)
  22:         {
  23:             vector::iterator iter = m_Vector.begin();
  24:             int i = 0;
  25:             while (iter != m_Vector.end())
  26:             {
  27:                 *iter++ = v[i];
  28:             }
  29:         }
  30:         else
  31:             throw invalid_argument("Vector size does not match.");
  32:  
  33:     }
  34:  
  35:     vectortemp():m_Vector(d)
  36:     {
  37:         vector::iterator iter = m_Vector.begin();
  38:         while (iter != m_Vector.end())
  39:         {
  40:             *iter = 0;
  41:         }
  42:     }
  43:  
  44:     const T &operator[](int index) const
  45:     {
  46:         return m_Vector[index];
  47:     }
  48:  
  49:     T &operator[](int index)
  50:     {
  51:         return m_Vector[index];
  52:     }
  53: };

警告提示出现在line 6。意思说vector需要用dll接口(__declspec(dllimport))从而使其被客户类vectortemp使用。__declspec(dllimport)用于所有需要从dll导入的对象,包括变量,函数,类等。而且必须用在定义前面。如果vectortemp中使用的不是一个模板类vector<>,这里会报错。因为头文件vector里只是vector类的声明。在vector实例化时,编译器会生成一份和头文件中一样的代码,一份本地类定义,当然加上模板参数,比如vector。所以用模板类不会出错,但编译器会友好地产生一个警告。警告不会影响程序运行,可以不用理睬。但是随着使用vectortemp的增加,警告会越来越多。这个确实很丑陋!解决方法有两个:直接用下面这个命令关闭警告。

   1: #pragma warning( disable: 4251 )

第一个方法还是丑陋了点,而且也不能了解内幕。我们需要一个显示地实例化模板,从而得到模板的一个定义。对一个非stl模板,可以这样:

   1: template class DLLExportExportMacro SomeTemplate<int>;
   2: SomeTemplate<int> y;

对于stl模板,如果只是相应的改成

   1: template class DLLExportExportMacro std::vector<int>;
   2: std::vector<int> y;

你会得到这个:

   1: warning C4251: 'std::_Vector_val<_Ty,_Alloc>::_Alval' : 
   2: class std::allocator<_Ty>' needs to have dll-interface to be used by clients of class 'std::_Vector_val<_Ty,_Alloc>'

因为stl::vector的实际定义是"std::vector >"。所以还要import std::allocator。

   1: template class DLLExportExportMacro std::allocator<int>;
   2: template class DLLExportExportMacro std::vector<int>;
   3: std::allocator<int> >;

方法二:导致链接错误

如果同时有两个DLL库用用显示实例方法导出vector,会导致vector的重定义。唯一的解决办法就是用#pragma warning( disable: 4251屏蔽警告。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值