织梦CMS - 轻松建站从此开始!

罗索

warning C4251: 'vectortemp::m_Vector' : class 'std::vector'

落鹤生 发布于 2015-01-02 21:52 点击:次 
个人理解,如果你用 VS2005 编译了一个 dll,然后用 VS2008 使用了这个 dll。如果 std::vector 在 VS2005/2008 中的实现不一样(内存布局),则就挂了。
TAG: STL  C4521  

症状:

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

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

警告提示出现在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 \
  3. 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屏蔽警告。

(scholfield)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201501/17183.html]
本文出处:CSDN博客 作者:scholfield 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容