您通常不应该对 std::copy_n 执行此操作,它假定提供的迭代器在递增 n 次时仍然有效:
将count 值从first 开始的范围精确复制到result 开始的范围。形式上,对于每个非负整数i < n,执行*(result + i) = *(first + i)。
(cppreference.com article on std::copy_n)
如果你能保证,那很好,但通常使用std::cin 这是不可能的。你可以很容易地让它解除对无效迭代器的引用:
默认构造的std::istream_iterator 称为流结束迭代器。当一个有效的std::istream_iterator 到达底层流的末尾时,它就等于流的末尾迭代器。取消引用或增加它会进一步调用未定义的行为。
(cppreference.com article on std::istream_iterator)
你的循环已经差不多了,尽管我可能会使用更强的终止条件来避免从“死”流中进行过多读取:
vector<int> v(n);
for(vector<int>::size_type i = 0; i < n; i++)
if (!cin >> v[i])
break;
实际上我很想把它包装成类似std::copy_n 的东西,但接受一个完整的“范围”,除了从 0 到 N 计数之外,它的边界还可以被验证.
实现可能如下所示:
template<class InputIt, class Size, class OutputIt>
OutputIt copy_atmost_n(InputIt first, InputIt last, Size count, OutputIt result)
{
for (Size i = 0; i < count && first != last; ++i)
*result++ = *first++;
return result;
}
你会这样使用它:
copy_atmost_n(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
N,
std::back_inserter(v)
);
现在您得到 M 个元素,其中 M 是提供的输入数或 N,以较小者为准。