使用 std::copy 而不是手动 for 循环复制动态数组有什么好处?
What is the benefit of using std::copy instead of manual for loop to copy dynamic array?
假设我有以下代码:
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() 并采取一些措施来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是吗?
回答您关于 std::copy
等的潜在好处的问题。人:
好处是,据推测,库实现可能比普通循环(例如 POD 类型的内在循环)更有效。例如,x86 上普通 C 中的 memcpy
可以更容易地优化为小尺寸的 rep movsb
。
至于警告:如果没有意义,应该报告为错误,然后 disabled/ignored。
在这种情况下,针对库代码对其自身实现的调用发出的警告是荒谬的,确实值得提交错误报告。
首先使用 Copy 而不是 for 循环,这对于巨大的循环来说更快 data.On 另一方面,你得到的错误有它自己的含义,警告提醒你函数参数值可能是错误的并且可能导致损坏在 future.i.e.缓冲区溢出的风险。我建议您采纳编译器自己的建议并使用 -D_SCL_SECURE_NO_WARNINGS.
最明显的优点是使用std::copy
明确表示
你在做什么。 reader 不必分析循环
想办法。第二个优点是代码行数更少。
这不是绝对优势;有时会更冗长
更好。但是当你使用更少的代码行来制作代码时
更清晰,绝对是优势
对于其余部分:理论上,编译器可以内置一个知识
标准功能,并应用它无法做到的优化
查找用户编写的函数或循环。在实践中,我不知道
任何编译器都可以。
在循环中使用 std::copy
有一些好处:
- 调用是自记录的。 reader 您的调用立即知道语句的意图是什么,而无需阅读注释或弄清楚循环在做什么
- 它可能针对您的情况针对简单类型进行了优化:
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable
source
- 更易于维护。您的容器将来更容易更换。您只需要将参数更改为复制而不是实现
正如其他评论所提到的,循环调用和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。相反,使用 #pragma disable
在本地禁用
假设我有以下代码:
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() 并采取一些措施来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是吗?
回答您关于 std::copy
等的潜在好处的问题。人:
好处是,据推测,库实现可能比普通循环(例如 POD 类型的内在循环)更有效。例如,x86 上普通 C 中的 memcpy
可以更容易地优化为小尺寸的 rep movsb
。
至于警告:如果没有意义,应该报告为错误,然后 disabled/ignored。
在这种情况下,针对库代码对其自身实现的调用发出的警告是荒谬的,确实值得提交错误报告。
首先使用 Copy 而不是 for 循环,这对于巨大的循环来说更快 data.On 另一方面,你得到的错误有它自己的含义,警告提醒你函数参数值可能是错误的并且可能导致损坏在 future.i.e.缓冲区溢出的风险。我建议您采纳编译器自己的建议并使用 -D_SCL_SECURE_NO_WARNINGS.
最明显的优点是使用std::copy
明确表示
你在做什么。 reader 不必分析循环
想办法。第二个优点是代码行数更少。
这不是绝对优势;有时会更冗长
更好。但是当你使用更少的代码行来制作代码时
更清晰,绝对是优势
对于其余部分:理论上,编译器可以内置一个知识 标准功能,并应用它无法做到的优化 查找用户编写的函数或循环。在实践中,我不知道 任何编译器都可以。
在循环中使用 std::copy
有一些好处:
- 调用是自记录的。 reader 您的调用立即知道语句的意图是什么,而无需阅读注释或弄清楚循环在做什么
- 它可能针对您的情况针对简单类型进行了优化:
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable source
- 更易于维护。您的容器将来更容易更换。您只需要将参数更改为复制而不是实现
正如其他评论所提到的,循环调用和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。相反,使用 #pragma disable