用VS2013运行boost::make_function_output_iterator的官方例子:
https://www.boost.org/doc/libs/1_68_0/libs/iterator/doc/function_output_iterator.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
struct string_appender { string_appender(std::string& s) : m_str(&s) {} void operator()( const std::string& x) const { *m_str += x; } std::string* m_str; }; int main( int , char *[]) { std::vector<std::string> x; x.push_back( "hello" ); x.push_back( " " ); x.push_back( "world" ); x.push_back( "!" ); std::string s = "" ; std::copy(x.begin(), x.end(), boost::make_function_output_iterator(string_appender(s))); std::cout << s << std::endl; return 0; } |
结果报如下的编译错误:
1
|
Error 1 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' c:program files (x86)microsoft visual studio 12.0vcincludexutility 2132 1
|
[解决方法]
加入预处理器(项目属性----C/C++----预处理----预处理器定义):
_SCL_SECURE_NO_WARNINGS
[分析]
这个编译错误是由于vc++的checked iterators规则(https://msdn.microsoft.com/en-us/library/aa985965.aspx), 加入_SCL_SECURE_NO_WARNINGS预处理器后, 编译会通过,然后将风险交给运行时,由于boost库比较完善,所以这种风险应该不存在.
把链接中的Checked iterators内容拷贝如下:
Checked IteratorsChecked iterators ensure that the bounds of your container are not overwritten. Checked iterators apply to both release builds and debug builds. For more information about how to use debug iterators when you compile in debug mode, see Debug Iterator Support. For information about how to disable warnings that are generated by checked iterators, see _SCL_SECURE_NO_WARNINGS. You can use the _ITERATOR_DEBUG_LEVEL preprocessor macro to enable or disable the checked iterators feature. If
When
When
A checked iterator refers to an iterator that will call checked_array_iterator Class and unchecked_array_iterator Class are the iterator adaptors that support checked iterators. When you compile by using // checked_iterators_1.cpp // cl.exe /Zi /MDd /EHsc /W4 #define _ITERATOR_DEBUG_LEVEL 1 #include <vector> #include <iostream> using namespace std; int main() { vector<int> v; v.push_back(67); int i = v[0]; cout << i << endl; i = v[1]; //triggers invalid parameter handler } This program prints "67" then pops up an assertion failure dialog box with additional information about the failure. Similarly, when you compile by using // checked_iterators_2.cpp // cl.exe /Zi /MDd /EHsc /W4 #define _ITERATOR_DEBUG_LEVEL 1 #include <vector> #include <iostream> using namespace std; int main() { vector<int> v; int& i = v.front(); // triggers invalid parameter handler } This program pops up an assertion failure dialog box with additional information about the failure. The following code demonstrates various iterator use-case scenarios with comments about each. By default, // checked_iterators_3.cpp // cl.exe /MTd /EHsc /W4 #include <algorithm> #include <array> #include <iostream> #include <iterator> #include <numeric> #include <string> #include <vector> using namespace std; template <typename C> void print(const string& s, const C& c) { cout << s; for (const auto& e : c) { cout << e << " "; } cout << endl; } int main() { vector<int> v(16); iota(v.begin(), v.end(), 0); print("v: ", v); // OK: vector::iterator is checked in debug mode // (i.e. an overrun causes a debug assertion) vector<int> v2(16); transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; }); print("v2: ", v2); // OK: back_insert_iterator is marked as checked in debug mode // (i.e. an overrun is impossible) vector<int> v3; transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; }); print("v3: ", v3); // OK: array::iterator is checked in debug mode // (i.e. an overrun causes a debug assertion) array<int, 16> a4; transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; }); print("a4: ", a4); // OK: Raw arrays are checked in debug mode // (an overrun causes a debug assertion) // NOTE: This applies only when raw arrays are given to C++ Standard Library algorithms! int a5[16]; transform(v.begin(), v.end(), a5, [](int n) { return n * 5; }); print("a5: ", a5); // WARNING C4996: Pointers cannot be checked in debug mode // (an overrun causes undefined behavior) int a6[16]; int * p6 = a6; transform(v.begin(), v.end(), p6, [](int n) { return n * 6; }); print("a6: ", a6); // OK: stdext::checked_array_iterator is checked in debug mode // (an overrun causes a debug assertion) int a7[16]; int * p7 = a7; transform(v.begin(), v.end(), stdext::make_checked_array_iterator(p7, 16), [](int n) { return n * 7; }); print("a7: ", a7); // WARNING SILENCED: stdext::unchecked_array_iterator is marked as checked in debug mode // (it performs no checking, so an overrun causes undefined behavior) int a8[16]; int * p8 = a8; transform(v.begin(), v.end(), stdext::make_unchecked_array_iterator(p8), [](int n) { return n * 8; }); print("a8: ", a8); } When you compile this code by using algorithm(1026) : warning C4996: 'std::_Transform1': 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' When run at the command line, the executable generates this output: v: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 v2: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 v3: 0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 a4: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 a5: 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 a6: 0 6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 a7: 0 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105 a8: 0 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120
|