- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
下面的代码片段从 std::cin
中读取三个整数;它将两个写入 numbers
并丢弃第三个:
std::vector<int> numbers(2);
copy_n(std::istream_iterator<int>(std::cin), 2, numbers.begin());
我希望代码从 std::cin
中准确读取两个整数,但事实证明这是一个正确的、符合标准的行为。这是对标准的疏忽吗?这种行为的基本原理是什么?
从 C++03 标准中的 24.5.1/1 开始:
After it is constructed, and every time ++ is used, the iterator reads and stores a value of
T
.
所以在上面的代码中,流迭代器在调用点已经读取了一个整数。从那时起,算法中迭代器的每次读取都是预读,产生从前一次读取缓存的值。
下一个标准的最新草案,n3225 ,这里似乎没有任何变化(24.6.1/1)。
在相关说明中,当前标准的 24.5.1.1/2 引用 istream_iterator(istream_type& s)
构造函数读取
Effects: Initializes
in_stream
withs
.value
may be initialized during construction or the first time it is referenced.
强调“值
可能被初始化...”而不是“应被初始化”。这听起来与 24.5.1/1 相矛盾,但也许这值得自己提出一个问题。
最佳答案
不幸的是,copy_n 的实现者未能解释复制循环中的预读。 Visual C++ 实现在 stringstream 和 std::cin 上都可以正常工作。我还检查了原始示例中 istream_iterator 是按行构造的情况。
这是来自 STL 实现的关键代码。
template<class _InIt,
class _Diff,
class _OutIt> inline
_OutIt _Copy_n(_InIt _First, _Diff _Count,
_OutIt _Dest, input_iterator_tag)
{ // copy [_First, _First + _Count) to [_Dest, ...), arbitrary input
*_Dest = *_First; // 0 < _Count has been guaranteed
while (0 < --_Count)
*++_Dest = *++_First;
return (++_Dest);
}
这是测试代码
#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <iterator>
int _tmain(int argc, _TCHAR* argv[])
{
std::stringstream ss;
ss << 1 << ' ' << 2 << ' ' << 3 << ' ' << 4 << std::endl;
ss.seekg(0);
std::vector<int> numbers(2);
std::istream_iterator<int> ii(ss);
std::cout << *ii << std::endl; // shows that read ahead happened.
std::copy_n(ii, 2, numbers.begin());
int i = 0;
ss >> i;
std::cout << numbers[0] << ' ' << numbers[1] << ' ' << i << std::endl;
std::istream_iterator<int> ii2(std::cin);
std::cout << *ii2 << std::endl; // shows that read ahead happened.
std::copy_n(ii2, 2, numbers.begin());
std::cin >> i;
std::cout << numbers[0] << ' ' << numbers[1] << ' ' << i << std::endl;
return 0;
}
/* Output
1
1 2 3
4 5 6
4
4 5 6
*/
关于c++ - std::istream_iterator<> 与 copy_n() 和 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5074122/
copy_n() 算法可以从源容器复制指定个数的元素到目的容器中。第一个参数是指向第一个源元素的输入迭代器,第二个参数是需要复制的元素的个数,第三个参数是指向目的容器的第一个位置的迭代器。这个算法会返
我如何使用 STL 算法来做到这一点? std::ifstream file(filename); std::vector buf; for(auto file_it = std::istreambu
我正在查看 N3485 25.3.1 [alg.copy] 中的 C++ 标准,它定义了 4 种算法: 复制 copy_backward copy_if copy_n 在 copy 的描述中,有这个注
下面的区别?哪一个有未定义的行为?两个? std::copy_n(asdf.begin(), asdf.size(), asdf.begin()); std::copy(asdf.begin(), a
我有一个结构和结构 vector : struct S { int Efficiency; int Number; }; std::vector Empl; 我尝试使用 copy_n
为什么在C++11中提供了_n版本的copy、fill和generate,为什么只有这些算法? 最佳答案 一般来说,STL 只提供原语,从中可以定义适当改编的变体。 SGI 文档给出了提供您提到的异常
如果我为 vector 保留一些空间,然后使用 std::copy_n() 在其中复制一些值,我会正确复制并访问这些值,但是 vector 的大小仍然为零。这是预期的行为吗?我是否应该改为调整 vec
根据 cppreference.com , reinterpret_cast: Converts between types by reinterpreting the underlying bit
我试图将输入行复制到多个 vector 中: #include #include #include #include #include #include int main(){ std
这么简单的问题。 template OutputIt copy_n(InputIt first, Size count, OutputIt result); 为什么 std::copy_n 为要复制的
我希望下面的 buf_iter 指向字符 n 字符在它开始的点之后。相反,它指向最后一个读取的字符。为什么是这样?即,如果我在 copy_n 之前和之后执行 in_stream.tellg(),它们的
下面的代码片段从 std::cin 中读取三个整数;它将两个写入 numbers 并丢弃第三个: std::vector numbers(2); copy_n(std::istream_iterato
我已通读 copy_n 文档 https://en.cppreference.com/w/cpp/algorithm/copy_n Exceptions 部分中有一行有趣的代码: 如果算法分配内存失败
我想用 C++ 打印出 std::vector 的内容。 这是我的: #include #include #include #include using namespace std; int
我试图实现一种反序列化方法,该方法采用输入迭代器并执行一系列 block 读取(使用 std::copy 和 std::copy_n )。像这样(只是一个例子): template InputIt
我是一名优秀的程序员,十分优秀!