STL提供 std :: copy 但是将它与具有固定大小的输出容器一起使用是很棘手的,因为输出迭代器没有边界检查
所以我发明了自己的东西,如下面的
template<class InputIterator , class OutputIterator>
void safecopy( InputIterator srcStart , InputIterator srcEnd ,
OutputIterator destStart , OutputIterator destEnd )
{
while ( srcStart != srcEnd && destStart != destEnd )
{
*destStart = *srcStart;
++srcStart;
++destStart;
}
}
int main()
{
std::istream_iterator<char> begin(std::cin), end;
char buffer[3];
safecopy( begin, end, buffer, buffer + 3 );
return 0;
}
问题:
答案 0 :(得分:5)
让我将评论推广到答案,所以我有更多的空间。
首先,您的实施看起来不错。
现在,为什么这不符合标准? (新标准增加了std::copy_n
,但这也有所不同。*)
这样想:strncopy
并不是一个“好”的想法;这不是一个可怕的想法。由于C没有任何动态数据结构,因此长度检查版本是您可以做的最好的。
但是在C ++中,这并不适合动态容器的一般概念:你很少想要覆盖一些元素,而是创建所有元素,你是std::copy
加上std::inserter
。 strncpy
是一个需要你预先分配目标数据结构的拐杖,但在C ++中我们可以做得比这更好。使用动态容器,迭代器和插入器,我们可以复制任何,而无需担心分配。
换句话说,您可能想到的任何抽象算法都应该有一个更好,更具体的方法来获取迭代器和迭代器范围(想想删除/擦除);算法的最终目标很少会产生一个受其他目标范围约束的输出范围。
总结:是的,你可以做到,但你可以做得更好。
*)虽然可以使用copy_n
加上min
的源和目标大小来创建有界副本。
答案 1 :(得分:1)
我会对您的实施做一个小调整。给它一个返回值。最终输出迭代器,或指示复制的元素数的整数。
我可以看到您的函数的主要用例是从输入流中读取固定大小的块,但您不知道它何时结束。如果它确实结束了,你需要某种方式来了解它,并且你需要知道在实际结束之前复制了多少元素。如果你知道复制了多少元素,并且它没有达到或超过输出范围的大小,那就是你知道它结束的方式。
答案 2 :(得分:0)
是。你又重新发明了轮子!
例如,您可以将std::copy
用作:
std::copy(s.begin(), s.begin() + 3 , buffer);
而不是这个,
safecopy(s.begin(), s.end() , buffer, buffer + 3);
以这种方式使用std::copy
并不比safecopy
更安全。
或者更好的是{C ++ 11附带的std::copy_n
:
std::copy_n(s.begin(), 3, buffer);
即使参数不是随机访问迭代器,这也可以工作。
至于何时使用std::vector<char>
,可以将其构造函数直接用作:
std::vector<char> v(s.begin(), s.end());
甚至不需要std::copy
。