【发布时间】:2020-01-27 20:25:39
【问题描述】:
我一直在阅读 Scott Meyers 的“Effective STL”,我注意到书中有很多例子,他通过使用std::copy 将元素复制到std::cout 来打印容器的内容。与使用基于范围的for 循环相比,这对我来说很难阅读(也许我只需要习惯它?)
// Given the following
std::vector<int> values = { 1, 2, 3, 4, 5, 6, 7, 8 };
// Print using `std::copy`
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, ", "));
// Print using a loop
for (const auto value : values)
{
std::cout << value << ", ";
}
这篇文章似乎表明使用std::copy 没有显着的性能提升:
有些人真的觉得std::copy 方法比基于范围的for 循环更具可读性吗?
如果我只想打印一半的值...
std::copy(values.begin(), values.begin() + values.size()/2, std::ostream_iterator<int>(std::cout, ", "));
...但即使那样我也可以这样做:
for (auto it = values.begin(); it != values.begin() + values.size()/2; ++it)
{
std::cout << *it << ", ";
}
所以我的问题是为什么有人更喜欢std::copy 方法?是否有任何情况可以证明std::copy 确实是更好的选择(或唯一的选择)?
【问题讨论】:
-
我认为这归结为纯粹基于意见。一般来说,标准算法不是魔法,你总是可以用手写循环替换它们,反之亦然,所以它主要是关于风格和偏好
-
请注意,您的最后一个示例在使用非随机访问迭代器时存在问题。例如
std::list。你不能iter + n,尽管你可以std::next(iter, n),但代价是线性复杂度。 -
有建议说:“没有原始循环”。如果您同意这一点,那么
std::copy就是解决方案。就个人而言,我不介意微不足道的原始循环,因此我将范围用于整个范围,或者将copy用于范围的任何部分。 -
也就是说,一旦我们得到
std::span,我可能会使用span和远程for。 -
检查该书的出版时间。它可能完全不了解 C++11,其中包括
auto变量(至少是那些具有当前含义的变量)和基于范围的 for 循环。