In the following code I get a warning with MSVC (C4996) that std::copy(errors.begin(),errors.end(),pErrors.get());
is not safe. It writes into the raw pointer. Is there an elegant and safe way to iterate over the elements?
The main goal is to prepare a built-in array for a call to a legacy function:
#include <iostream>
#include <initializer_list>
#include <memory>
#include <algorithm>
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
}
void print_errors(std::initializer_list<int> errors)
{
std::unique_ptr<int[]> pErrors{new int[errors.size()]};
std::copy(errors.begin(),errors.end(),pErrors.get()); // warning C4996
print_errors_old_function(errors.size(),pErrors.get());
}
int main()
{
print_errors({234,253,334});
return 0;
}
It seems a range based for loop is not possible with std::unique_ptr<int[]>
and that regular for loop would arguably less readable than std::copy
.
答案 0 :(得分:1)
您不需要std::unique_ptr
。 std::vector
可以正常工作,因为&v[0]
可以保证为您提供指向内部缓冲区的指针,当然它还有一个size()
成员函数可用于与C函数接口。从C ++ 11开始,还有data()
,它看起来比&v[0]
更好。
#include <iostream>
#include <initializer_list>
#include <vector>
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
}
void print_errors(std::initializer_list<int> errors)
{
std::vector<int> vErrors(errors);
print_errors_old_function(vErrors.size(), &vErrors[0] /* or vErrors.data() in C+11 */ );
}
int main()
{
print_errors({234,253,334});
return 0;
}
注意如何摆脱警告。
答案 1 :(得分:1)
另一个答案是正确的,但请注意这是这样的函数:
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
delete[] pErrors; // note this function effectively "consumes" the input
}
您将无法使用此方法,因为无法释放vector
内存的所有权。您必须按照问题的方式使用std::unique_ptr
,但必须使用pErrors.release()
代替pErrors.get()
。
Visual C ++抱怨因为在标准中定义的几个函数,但它认为它们是“不安全的”,这使得符合标准的代码不可编译。有时,Microsoft提供的解决方法只能在Visual C ++上使用。
你可以做什么(选择其中之一):
_SCL_SECURE_NO_WARNINGS
。 (禁用这些警告)