假设我有以下代码:
int* intPtr = new int[5];
// ...do stuff...
现在我想将intPtr复制到一个新的,相同的数组:
int* newIntPtr = new int[5];
这可以使用简单的for循环或std :: copy():
使用for循环
for (int i = 0; i < 5; i++)
*(newIntPtr + i) = *(intPtr + i);
使用std :: copy()
std::copy( intPtr, intPtr + 5, newIntPtr );
使用std :: copy(),我在Visual Studio中收到警告:
warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe...
我可以使用stdext::checked_array_iterator<int*>
让警告消失:
std::copy(intPtr, intPtr + 5, stdext::checked_array_iterator<int*>(newIntPtr, 5));
但这意味着代码不会在除Visual Studio之外的其他任何内容上编译。
那么,我该如何解决这个问题呢?我应该使用简单的for循环并有效地避免警告,还是应该使用std :: copy()并做一些事情来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是它?
答案 0 :(得分:4)
在循环中使用std::copy
有一些好处:
实际上,如果值类型为TriviallyCopyable,则std :: copy的实现会避免多个赋值并使用批量复制函数,例如std :: memmove source
正如其他评论所提到的,循环和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。而是使用#pragma disable
答案 1 :(得分:1)
最明显的优势是使用std::copy
明确说明
你在做什么。读者不必分析循环
想办法。第二个优点是它的代码行数较少。
这不是绝对的优势;有时候更冗长一点
更好。但是当你使用较少的代码行来制作代码时
更清楚,这绝对是一个优势。
对于其他人:理论上,编译器可以具有内置的a知识 标准函数,并应用它无法实现的优化 找到用户编写的函数或循环。在实践中,我不知道 任何编译器的。
答案 2 :(得分:0)
回答有关std::copy
等潜在好处的问题。人:
据推测,好处是,库实现可能比普通循环更有效(例如,POD类型的内在函数)。例如,对于小尺寸,x86上的普通C中的memcpy
可以更容易地优化为rep movsb
。
至于警告:如果没有意义,应该将其报告为错误,然后禁用/忽略。
在这种情况下,为库代码对其自己的实现进行的调用发出的警告是荒谬的,并且确实需要一个错误报告。
答案 3 :(得分:0)
首先使用Copy代替for循环,对于大数据来说更快。另一方面,你得到的错误有它自己的意思,警告提醒你功能参数值可能是错误的,可能会造成损害在将来。我缓冲区溢出的风险。我建议你采用编译器自己的建议并使用-D_SCL_SECURE_NO_WARNINGS。