在C++ PRIMER中模拟实现vector容器所给的代码中,如果你用的是vs 2012的话,那么你会发现根本就不能通过编译,这时应该怎么办呢?
有问题代码为:
uninitialized_copy(elements , first_free , newelements) ;
上述代码的目的是把elements到first_free之间的内存中的数据复制到以newelements开始的内存中
首先把这段代码放到vs 2010进行编译、运行你会发现只是弹出了如下的信息,但是能正确运行。
warning C4996: 'std::_Uninitialized_copy0': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
在vs 2012中进行编译会弹出如下信息:
error C4996: 'std::_Uninitialized_copy0': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
有上述代码的功能我想可以想到用如下的代码替代它:
copy(elements , first_free , newelements) ;
此时你会发现在vs 2012中的编译信息如下:
error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
而在vs 2010中却仍可以正确编译并运行,所显示的编译信息如下:
warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
从编译的信息来看vs 2012有点矛盾的地方,也即error C4996 ... To disable this warning前面说是error后面却成了warning,逻辑上不太相符,当然这不排除是汉化引起的。
在vs 2012中不能像C++ PRIMER中所描述的那样使用这两个函数的原因是在vs 2012中提升了安全机制,在这里如果我们还是想直接使用这两个函数那么,我们可以在使用前添加如下的宏定义:
#ifndef _SECURE_SCL
#define _SECURE_SCL 0
#else
#undef _SECURE_SCL
#define _SECURE_SCL 0
#endif
或
#ifndef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#else
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif
或者加入预处理器:(项目属性----C/C++----预处理----预处理器定义):
_SCL_SECURE_NO_WARNINGS
当然我们也可以不用这两个函数,而使用其它的函数来完成相同的功能,如以下几个函数:
1、
用头文件algorithm中提供的模板函数
copy
(FwdIt first, FwdIt last, const T& x)来提供:
添加上述的宏定义,然后用
copy(elements , first_free , newelements) ;
2、用头文件memory中allocator类提供的操作
constuct(p , t)来提供:
for(ptrdiff_t i=0 ; i
alloc.construct(newelements+i , elements[i]) ;
3、用头文件memory中提供的模板函数
uninitialized_fill(FwdIt first, FwdIt last, const T& x)来提供:
for(ptrdiff_t i=0 ; i
uninitialized_fill(newelements+i , newelements+i+1 , elements[i]) ;
4、用头文件algorithm中提供的模板函数
fill(FwdIt first, FwdIt last, const T& x)来提供:
for(ptrdiff_t i=0 ; i
fill(newelements+i , newelements+i+1 , elements[i]) ;
5、用头文件memory.h中提供的函数
memcpy( void *
dest, const void *
src, size_t
count )或
memmove( void *
dest, const void *
src, size_t
count )来提供:(T是所写的模板类的模板参数)
memcpy(newelements , elements , size*sizeof(T)) ;
或
memmove(newelements , elements , size*sizeof(T)) ;
下面对上面用到的宏进行简单的介绍:
_SECURE_SCL (SCL)
macro defines whether Checked Iterators(
Checked iterators ensure that the bounds of your container are not overwritten
) are enabled.
If defined as 1, unsafe iterator use causes a runtime error and the program is terminated.
If defined as 0, checked iterators are disabled.
In debug mode, the default value for _SECURE_SCL is 1, meaning checked iterators are enabled.
In release mode, the default value for _SECURE_SCL is 0.
_HAS_ITERATOR_DEBUGGING (HID) macro defines whether the iterator debugging feature is enabled in a debug build.
By default, iterator debugging is enabled.
The following section describes the possible values of the SCL and HID macros :
SCL=0 Disables checked iterators.
SCL=1
Enables checked iterators.
HID=0
Disables iterator debugging in debug builds.
HID=1
Enables iterator debugging in debug builds. HID cannot be enabled in release builds.
The
_ITERATOR_DEBUG_LEVEL (IDL) macro supersedes and combines the functionality of the _SECURE_SCL (SCL) and _HAS_ITERATOR_DEBUGGING (HID) macros.
The following table describes how the IDL macro values supersede the SCL and HID macro values :
Compilation mode |
New macro |
Old macros |
Description |
Debug |
|
|
|
|
IDL=0 |
SCL=0, HID=0 |
Disables checked iterators and disables iterator debugging. |
|
IDL=1 |
SCL=1, HID=0 |
Enables checked iterators and disables iterator debugging. |
|
IDL=2 (Default) |
SCL=(does not apply), HID=1 |
By default, enables iterator debugging; checked iterators are not relevant. |
Release |
|
|
|
|
IDL=0 (Default) |
SCL=0 |
By default, disables checked iterators. |
|
IDL=1 |
SCL=1 |
Enables checked iterators; iterator debugging is not relevant. |