Is there a safe way to iterate over std::unique_ptr<int[]>?

时间:2016-03-04 18:14:23

标签: c++ c++11

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.

2 个答案:

答案 0 :(得分:1)

您不需要std::unique_ptrstd::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 ++上使用。

你可以做什么(选择其中之一):

  • 使用建议的Microsoft的解决方法
  • 禁用SDL检查(这些检查将这些警告变为错误)
  • 在项目中定义_SCL_SECURE_NO_WARNINGS。 (禁用这些警告)