- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我希望下面的 buf_iter
指向字符 n
字符在它开始的点之后。相反,它指向最后一个读取的字符。为什么是这样?即,如果我在 copy_n 之前和之后执行 in_stream.tellg(),它们的区别不是 n
而是 (n-1)
。如果我用 in_stream.read
读取了 n
个字符,那么该位置将前进 n
。
std::istreambuf_iterator<char> buf_iter(in_stream);
std::copy_n(buf_iter, n, sym.begin());
我查看了实现,它显然是故意这样做的,跳过了最后的增量。
另一篇文章 here 提到当从迭代器连接到 cin
时递增它会导致读取次数过多,因为读取是在 operator++() 上完成的
。这听起来像是 cin
的问题 - 为什么没有在 operator*()
上完成读取?
标准是否在任何地方指定了这一点?我看到的文档没有提到 from 迭代器会发生什么,而且我看到了两个不同的页面,它们给出了执行每种行为的“可能的正确实现”:
template< class InputIt, class Size, class OutputIt>
OutputIt copy_n(InputIt first, Size count, OutputIt result)
{
if (count > 0) {
*result++ = *first;
for (Size i = 1; i < count; ++i) {
*result++ = *++first;
}
}
return result;
}
while at cplusplus.com we have :
template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
{
while (n>0) {
*result = *first;
++result; ++first;
--n;
}
return result;
}
两者都不读取并在结果中产生相同的内容。但是,第一个只会增加“第一个”迭代器 n-1
次,第二个只会增加 n
次。
什么给了?如何编写可移植代码?我可以使用 tellg
然后使用 seekg
但我还不如手动执行循环(啊!)。
请注意,我不是在调用 copy_n
之后尝试从迭代器中读取,而是我想在调用 copy_n
之后从底层流中读取,问题是copy_n
指向的字节短于我预期的位置。现在我要使用有点可怕但显然是便携的:
auto pos = in_stream.tellg();
std::istreambuf_iterator<char> buf_iter(in_stream);
std::copy_n(buf_iter, cl, sym.begin());
in_stream.seekg(pos + cl);
uint64_t foo;
in_stream.read(reinterpret_cast<char *>(&foo), 8);
顺便说一句,如果不清楚,我试图避免将数据复制到缓冲区中,然后再复制到字符串 sym
。
@DaveS:离开我的具体问题,这里有一个简单的程序,由于输入迭代器最后一次没有递增,所以它没有输出我所期望的:
#include <algorithm>
#include <string>
#include <iostream>
#include <fstream>
int main(int argc, const char * argv[])
{
std::ifstream in("numbers.txt");
std::istreambuf_iterator<char> in_iter(in);
std::ostreambuf_iterator<char> out_iter(std::cout);
std::copy_n(in_iter, 3, out_iter);
std::cout << std::endl;
std::copy_n(in_iter, 3, out_iter);
std::cout << std::endl;
std::copy_n(in_iter, 3, out_iter);
std::cout << std::endl;
return 0;
}
输入文件就是"0123456789\n"
我明白了:
012
234
456
由于 istreambuf_iterator::operator++()
的副作用,如果实现 copy_n
来增加输入迭代器 n,这将给出不同的结果
次。
@aschepler:需要捕获本地参数,但我会用它:
std::generate_n(sym.begin(), cl, [&in_stream](){ return in_stream.get(); });
最佳答案
许多 std::copy_n
实现增加 n-1 次的原因是由于与 istream_iterator
的交互,以及通常是如何实现的。
例如,如果您有一个包含整数的输入文件
std::vector<int> buffer(2);
std::istream_iterator<int> itr(stream); // Assume that stream is an ifstream of the file
std::copy_n(itr, 2, buffer.begin());
因为 istream_iterator
被指定为在递增时读取(以及在构造或第一次取消引用时),如果 std::copy_n
将输入迭代器递增 2 次,您实际上会从文件中读取 3 个值。当 copy_n
内的本地迭代器超出范围时,第三个值将被丢弃。
istreambuf_iterator
没有相同的交互,因为它实际上并不像大多数 istream_iterators
那样将值从流中复制到本地拷贝中,但是 copy_n
仍然如此。
编辑:如果 copy-N 增加 N 次则丢失数据的示例(cplusplus.com 描述,这似乎不正确)。请注意,这实际上仅适用于 istream_iterators
或其他在增量时读取和删除其基础数据的迭代器。
std::istream_iterator<int> itr(stream); // Reads 1st value
while(n > 0) // N = 2 loop start
{
*result = *first;
++result; ++first; // Reads 2nd value
--n; // N: 1
// N = 1 loop start
*result = *first;
++result; ++first; // Reads 3rd value
--n; // N :0
// Loop exit
}
return result;
关于c++ - 为什么 std::copy_n 不增加输入迭代器 n 次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23301162/
我正在开发一个小型图书馆,我需要做的一件事是让访问者访问一些数据并返回结果。 在一些较旧的 C++ 代码中,访问者需要声明一个 typedef return_type .例如,boost::stati
我正在尝试使用std:map类型的键和值制作std::any Visual Studio 2017 std::map m("lastname", "Ivanov"); std::cout (m["la
我已经在 C++ 的 map 中声明了一个集合为 std::map> .如何循环访问或打印设定值? 最佳答案 如果你知道如何迭代 std::map或 std::set单独地,您应该可以毫无问题地组合迭
如何循环? 我已经试过了: //----- code std::vector >::iterator it; for ( it = users.begin(); it != users.end();
我有两个用例。 A.我想同步访问两个线程的队列。 B.我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。 对于用例 A,我看到了使用 std::lock_
我正在查看这两种类型特征的文档,但不确定有什么区别。我不是语言律师,但据我所知,它们都适用于“memcpy-able”类型。 它们可以互换使用吗? 最佳答案 不,这些术语不能互换使用。这两个术语都表示
我有以下测试代码,其中有一个参数 fS,它是 ofstream 的容器: #include #include #include #include int
这是这个问题的延续 c++ function ptr in unorderer_map, compile time error 我试图使用 std::function 而不是函数指针,并且只有当函数是
std::unordered_map str_bool_map = { {"a", true}, {"b", false}, {"c", true} }; 我们可以在此映射上使
我有以下对象 std::vector> vectorList; 然后我添加到这个使用 std::vector vec_tmp; vec_tmp.push_back(strDRG); vec_tmp.p
为什么 std::initializer_list不支持std::get<> , std::tuple_size和 std::tuple_element ?在constexpr中用得很多现在的表达式,
我有一个像这样定义的变量 auto drum = std::make_tuple ( std::make_tuple ( 0.3f , Ex
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
问题 我正在尝试将 lambda 闭包传递给 std::thread,它使用任意封闭参数调用任意封闭函数。 template std::thread timed_thread(Function&& f
我想创建一个模板类,可以容纳容器和容器的任意组合。例如,std::vector或 std::map ,例如。 我尝试了很多组合,但我必须承认模板的复杂性让我不知所措。我编译的关闭是这样的: templ
我有一个 std::vector>我将其分配给相同类型的第二个 vector 。 我收到这个编译器错误: /opt/gcc-8.2.0/include/c++/8.2.0/bits/stl_algob
有时候,我们有一个工厂可以生成一个 std::unique_ptr vector ,后来我们想在类/线程/你命名的之间共享这些指针。因此,最好改用 std::shared_ptr 。当然有一种方法可以
这个问题在这里已经有了答案: Sorting a vector of custom objects (14 个答案) 关闭 6 年前。 我创建了一个 vector vector ,我想根据我定义的参
我有三个类(class)成员: public: std::vector > getObjects(); std::vector > getObjects() const; privat
我是一名优秀的程序员,十分优秀!